類庫探源——System.Drawing.Bitmap


一、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 }
View Code

 

附本小節代碼下載

 

二、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 }
View Code

 

附本小節代碼下載

 

效果

原圖:

灰度化圖:

 

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 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM