日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺析C#byte數(shù)組轉(zhuǎn)化成圖像的實(shí)現(xiàn)

C# byte數(shù)組轉(zhuǎn)換為8bit灰度圖像的問題類似的文章在網(wǎng)上可以看到不少,但多多少少都存在一些問題。這兩天做實(shí)驗室的項目用到這個功能,我從頭把它整理了一遍。在看代碼之前,首先解釋幾個問題。

龍井ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

1、byte數(shù)組存放的是圖像每個像素的灰度值,byte類型正好是從0~255,存放8bit灰度圖像的時候,一個數(shù)組元素就是一個像素的灰度值。僅有這個數(shù)組還不足以恢復(fù)出原來的圖像,還必須事先知道圖像的長、寬值;

2、創(chuàng)建Bitmap類的時候必須指定PixelFormat為Format8bppIndexed,這樣才***圖像本身的特性;

3、Bitmap類雖然提供了GetPixel()、SetPixel()這樣的方法,但我們絕對不能用這兩個方法來進(jìn)行大規(guī)模的像素讀寫,因為它們的性能實(shí)在很囧;

4、托管代碼中,能不用unsafe就盡量不用。在.NET 2.0中已經(jīng)提供了BitmapData類及其LockBits()、UnLockBits()操作,能夠安全地進(jìn)行內(nèi)存讀寫;
 
5、圖像的width和它存儲時的stride是不一樣的。位圖的掃描線寬度一定是4的倍數(shù),因此圖像在內(nèi)存中的大小并不是它的顯示大?。?/p>

6、Format8bppIndexed類型的PixelFormat是索引格式,其調(diào)色板并不是灰度的而是偽彩,因此需要我們對其加以修改。

代碼如下,解說寫在注釋里了:

 
 
 
 
  1. ///   
  2. /// 將一個字節(jié)數(shù)組轉(zhuǎn)換為8bit灰度位圖  
  3. ///   
  4. /// 顯示字節(jié)數(shù)組  
  5. /// 圖像寬度  
  6. /// 圖像高度  
  7. /// 位圖  
  8. public static Bitmap ToGrayBitmap(byte[] rawValues, int width, int height)  
  9. {  
  10. //// 申請目標(biāo)位圖的變量,并將其內(nèi)存區(qū)域鎖定  
  11. Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);  
  12. BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height),  
  13.  ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);  
  14.  
  15. //// 獲取圖像參數(shù)  
  16. int stride = bmpData.Stride;  // 掃描線的寬度  
  17. int offset = stride - width;  // 顯示寬度與掃描線寬度的間隙  
  18. IntPtr iptr = bmpData.Scan0;  // 獲取bmpData的內(nèi)存起始位置  
  19. int scanBytes = stride * height;// 用stride寬度,表示這是內(nèi)存區(qū)域的大小  
  20.  
  21. //// 下面把原始的顯示大小字節(jié)數(shù)組轉(zhuǎn)換為內(nèi)存中實(shí)際存放的字節(jié)數(shù)組  
  22. int posScan = 0, posReal = 0;// 分別設(shè)置兩個位置指針,指向源數(shù)組和目標(biāo)數(shù)組  
  23. byte[] pixelValues = new byte[scanBytes];  //為目標(biāo)數(shù)組分配內(nèi)存  
  24.  
  25.   for (int x = 0; x < height; x++)  
  26. {  
  27.  //// 下面的循環(huán)節(jié)是模擬行掃描  
  28.  for (int y = 0; y < width; y++)  
  29.  {  
  30.  pixelValues[posScan++] = rawValues[posReal++];  
  31.  }  
  32.  posScan += offset;  //行掃描結(jié)束,要將目標(biāo)位置指針移過那段“間隙”  
  33. }  
  34.    
  35. //// 用Marshal的Copy方法,將剛才得到的內(nèi)存字節(jié)數(shù)組復(fù)制到BitmapData中  
  36. System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes);  
  37. bmp.UnlockBits(bmpData);  // 解鎖內(nèi)存區(qū)域  
  38.    
  39. //// 下面的代碼是為了修改生成位圖的索引表,從偽彩修改為灰度  
  40. ColorPalette tempPalette;  
  41. using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))  
  42. {  
  43.  tempPalette = tempBmp.Palette;  
  44. }  
  45. for (int i = 0; i < 256; i++)  
  46. {  
  47.  tempPalette.Entries[i] = Color.FromArgb(i, i, i);  
  48. }  
  49.  
  50. bmp.Palette = tempPalette;  
  51.    
  52. //// 算法到此結(jié)束,返回結(jié)果  
  53. return bmp;  
  54. }  

下面是我用來測試的代碼片段:

 
 
 
 
  1.   static void Main(string[] args)  
  2.   {  
  3.   byte[] bytes = new byte[10000];  
  4.   int k = 0;  
  5.  
  6.   for (int i = 0; i < 100; i++)  
  7.   {  
  8. for (int j = 0; j < 100; j++)  
  9. {  
  10. bytes[k++] = (byte)(i + j);  
  11. }  
  12.   }  
  13.  
  14.   Bitmap bmp = ToGrayBitmap(bytes, 100, 100);  
  15.  
  16.   bmp.Save(@"d:\test.png",   
  17.  
  18. System.Drawing.Imaging.ImageFormat.Png);  
  19.   }  

結(jié)果應(yīng)該顯示成下面的樣子:

如果沒有修改過調(diào)色板,則會顯示出下面的色彩斑斕的圖像:

C#byte數(shù)組轉(zhuǎn)化成圖像的相關(guān)內(nèi)容就向你介紹到這里,希望對你了解和學(xué)習(xí)C#byte數(shù)組轉(zhuǎn)化成圖像有所幫助。

【編輯推薦】

  1. C#靜態(tài)方法應(yīng)用實(shí)例詳解
  2. C#反射概念以及實(shí)例詳解
  3. C#反射命名空間淺析
  4. C#靜態(tài)類和靜態(tài)類成員詳解
  5. C# byte數(shù)組常用擴(kuò)展淺析

文章名稱:淺析C#byte數(shù)組轉(zhuǎn)化成圖像的實(shí)現(xiàn)
當(dāng)前地址:http://www.dlmjj.cn/article/cohggoe.html