一、System.Drawing.Bitmap
Bitmap 類: 封裝GDI+ 位圖,此位圖由圖形圖像及其屬性的像素數據組成。Bitmap 是用於處理由像素定義的圖像的對象
命名空間: System.Drawing
程序集: System.Drawing.dll
繼承關系:
原型定義:
[SerializableAttribute] [ComVisibleAttribute(true)] public sealed class Bitmap : Image
備注:
GDI+ 支持下列文件格式:BMP、GIF、EXIF、JPG、PNG 和 TIFF
構造器:
// 從指定的現有圖像初始化 Bitmap 類的新實例 public Bitmap(Image original) // 從指定的數據流初始化 Bitmap 類的新實例 public Bitmap(Stream stream) // 從指定的文件初始化 Bitmap 類的新實例 (filename 位圖文件的名稱和路徑) public Bitmap(string filename)
注意:在 在釋放 Bitmap 之前,此filename 對應的文件將一直保持鎖定狀態
常用實例方法:
1. 獲取指定像素的顏色 public Color GetPixel(int x,int y) 參數: x : 指定像素的 x 坐標 y : 指定像素的 y 坐標 返回值: System.Drawing.Color 2. 設置指定像素的顏色 public void SetPixel(int x,int y,Color color) 參數: x : 指定像素的 x 坐標 y : 指定像素的 y 坐標 color: 顏色 3. 將 Bitmap 鎖定到系統內存中 [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public BitmapData LockBits(Rectangle rect,ImageLockMode flags,PixelFormat format) 參數: rect: 指定要鎖定 Bitmap 部分 flags: 指定 Bitmap 的訪問級別(讀/寫) format: 指定此 Bitmap 的數據格式 返回值: BitmapData 包含有關此鎖定操作的信息 4. 從系統內存解鎖此 Bitmap UnlockBits(BitmapData) 5. 使默認的透明顏色對此 Bitmap 透明 MakeTransparent() MakeTransparent(Color transparentColor)
透明化的例子

1 using System; 2 using System.Drawing; 3 4 class App 5 { 6 static void Main() 7 { 8 var img = new Bitmap(@"透明化.png"); 9 img.MakeTransparent(); 10 img.Save(@"透明化_處理后.png") ; 11 12 // MakeTransparent(Color transparentColor) 對指定Color 也執行透明操作 13 img.MakeTransparent(Color.FromArgb(0x1364C4)); 14 img.Save(@"透明化_處理后_0x1364C4.png"); 15 } 16 }
附本小節代碼下載
二、System.Drawing.Imaging.ImageLockMode
ImageLockMode 枚舉:指定傳遞給 LockBits 方法的標志參數的標志。 LockBits 方法可鎖定圖像的一部分,以便讀取或寫入其像素數據
枚舉項:
ReadOnly: 指定鎖定圖像的一部分以便讀取
WriteOnly: 指定鎖定圖像的一部分以便寫入
ReadWrite: 指定鎖定圖像的一部分以便讀取和寫入
三、System.Drawing.Imaging.PixelFormat
PixelFormat 枚舉:指定圖像中每個像素的顏色數據的格式
枚舉項:見MSDN
四、System.Drawing.Imaging.BitmapData
BitmapData 類:指定位圖圖像的屬性。BitmapData 類由 Bitmap 類的 LockBits 和 UnlockBits 方法使用。 不可繼承
命名空間: System.Drawing.Imaging
程序集: System.Drawing.dll
繼承關系:
實例屬性:
Height //獲取或設置Bitmap 對象的像素高度,有時也稱掃描行數 Width //獲取或設置Bitmap 對象的像素寬度,這可以看做是一個掃描行中的像素數 PixelFormat: //獲取或設置此 BitmapData對象的 Bitmap 對象中像素信息的格式 Scan0 //獲取或設置位圖中第一個像素數據的地址。它可看成是位圖中的第一個掃描行 Stride //獲取或設置 Bitmap 對象的跨距寬度(也稱為掃描寬度)
五、System.Drawing.Color
Color 結構:表示一種 ARGB 顏色(alpha、紅色、綠色、藍色)。
命名空間: System.Drawing
程序集: System.Drawing.dll
靜態屬性: 各種顏色(如 Color.Red、Color.Yellow 等)
靜態方法:
Color.FromArgb(int argb) 例子: SolidBrush trnsRedBrush = new SolidBrush(Color.FromArgb(0x78FF0000)); 從四個 ARGB 分量(alpha、紅色、綠色和藍色)值創建 Color 結構。 盡管此方法允許為每個分量傳遞 32 位值,但每個分量的值僅限於 8 位 // 78 FF 00 00 public static Color FromArgb(int alpha,int red,int green,int blue)
六、例子 彩色圖像簡單灰度化
公式:
Gray(i,j) = 0.229*R(i,j) + 0.587*G(i,j) + 0.114*B(i,j)
代碼

1 using System; 2 using System.Drawing; 3 using System.Drawing.Imaging; 4 5 class App 6 { 7 static void Main() 8 { 9 using(var img = new Bitmap(@"BingWallpaper.jpg")) 10 { 11 Rectangle rect = new Rectangle(0, 0, img.Width, img.Height); 12 BitmapData bmpData = img.LockBits(rect,ImageLockMode.ReadWrite,img.PixelFormat); 13 IntPtr ptr = bmpData.Scan0; 14 int bytes = img.Width * img.Height * 3; 15 byte[] rgbValues = new byte[bytes]; 16 System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); 17 double colorTemp = 0; 18 for (int i = 0; i < rgbValues.Length; i += 3) 19 { 20 colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114; 21 rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp; 22 } 23 System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 24 img.UnlockBits(bmpData); 25 26 img.Save(@"BingWallpaper_灰度化.jpg"); 27 } 28 } 29 }
附本小節代碼下載
效果
原圖:
灰度化圖:
2014-12-21 更新:
1. Format24bppRgb : 每個像素24位,紅色、綠色、藍色分量分別使用8位,它們的順序是 藍、率、紅(BGR)
2. Stride 即步幅也稱掃描寬度,系統規定它必須是4的倍數
3. BmpData.Width 與 BmpData.Stride 的關系 BmpData.Stride = BmpData.Width * 3 + X(X為保留字節,用來調節,使Stride 能被4整除)
下面兩幅圖說明 Height、 Width 與 Stride
Scan0
|
|---------Stride-----------------|
|---------Width-------------| | 注:Width是圖片(BGR作為一個單位)寬度
BGR BGR BGR BGR BGR BGR XX
BGR BGR BGR BGR BGR BGR XX
.
.
注:BGR為一個像素,是byte[3]的數組
下圖來自《C#數字圖像處理算法》一書
4. 代碼修正
六、例子 彩色圖像簡單灰度化 這節的代碼有問題,因為我給的圖片Width正好是4的倍數,所以 Width *3 也是4的倍數,所以不需要額外字節,但如果Width不是4的倍數,代碼就不能得到正確的結果了,下面將修正后的代碼貼出

1 using System; 2 using System.Drawing; 3 using System.Drawing.Imaging; 4 5 class App 6 { 7 static void Main() 8 { 9 using(var img = new Bitmap(@"test.png")) 10 { 11 Rectangle rect = new Rectangle(0, 0, img.Width, img.Height); 12 BitmapData bmpData = img.LockBits(rect,ImageLockMode.ReadWrite,img.PixelFormat); 13 IntPtr ptr = bmpData.Scan0; 14 15 // 用步幅表示 16 int bytes = bmpData.Stride * bmpData.Height; 17 byte[] rgbValues = new byte[bytes]; 18 System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); 19 double colorTemp = 0; 20 int bmpStride = bmpData.Stride; 21 22 for(int bmpheight = 0; bmpheight < bmpData.Height; bmpheight++) 23 { 24 // 只處理實際 Height , 不理會未用空間 25 for(int bmpwidth = 0; bmpwidth < bmpData.Width *3; bmpwidth += 3) 26 { 27 colorTemp = rgbValues[bmpheight * bmpStride + bmpwidth + 2] * 0.299 + 28 rgbValues[bmpheight * bmpStride + bmpwidth + 1] * 0.587 + 29 rgbValues[bmpheight * bmpStride + bmpwidth] * 0.114; 30 31 rgbValues[bmpheight * bmpStride + bmpwidth] = 32 rgbValues[bmpheight * bmpStride + bmpwidth + 1] = 33 rgbValues[bmpheight * bmpStride + bmpwidth + 2] = (byte)colorTemp; 34 } 35 } 36 37 System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 38 img.UnlockBits(bmpData); 39 40 img.Save(@"BingWallpaper_灰度化.jpg"); 41 } 42 } 43 }