2012-08-16 139 views
3

我有一個數組,如byte[] pixels。有沒有辦法在不復制數據的情況下從pixels創建一個bitmap對象?我有一個小圖形庫,當我需要在WinForms窗口上顯示圖像時,我只需將該數據複製到一個bitmap對象,然後使用draw方法。我可以避免這種複製過程嗎?我記得我在某處看到過它,但也許我的記憶力很差。從數組創建位圖對象

編輯:我試過這個代碼,它的工作原理,但這是安全的嗎?

byte[] pixels = new byte[10 * 10 * 4]; 

pixels[4] = 255; // set 1 pixel 
pixels[5] = 255; 
pixels[6] = 255; 
pixels[7] = 255; 

// do some tricks 
GCHandle pinnedArray = GCHandle.Alloc(pixels, GCHandleType.Pinned); 
IntPtr pointer = pinnedArray.AddrOfPinnedObject(); 

// create a new bitmap. 
Bitmap bmp = new Bitmap (10, 10, 4*10, PixelFormat.Format32bppRgb, pointer); 

Graphics grp = this.CreateGraphics(); 
grp.DrawImage (bmp, 0, 0); 

pixels[4+12] = 255; // add a pixel 
pixels[5+12] = 255; 
pixels[6+12] = 255; 
pixels[7+12] = 255; 

grp.DrawImage (bmp, 0, 40); 
+0

這是有點相關我想:http://stackoverflow.com/questions/1580130/high-speed-performance c-sharp-image-filtering-in-c-sharp – Patrick 2012-08-16 14:52:58

回答

6

有一個構造函數的指針,原始圖像數據:

Bitmap Constructor (Int32, Int32, Int32, PixelFormat, IntPtr)

例子:

byte[] _data = new byte[] 
{ 
    255, 0, 0, 255, // Blue 
    0, 255, 0, 255, // Green 
    0, 0, 255, 255, // Red 
    0, 0, 0, 255, // Black 
}; 

var arrayHandle = System.Runtime.InteropServices.GCHandle.Alloc(_data, 
     System.Runtime.InteropServices.GCHandleType.Pinned); 

var bmp = new Bitmap(2, 2, // 2x2 pixels 
    8,      // RGB32 => 8 bytes stride 
    System.Drawing.Imaging.PixelFormat.Format32bppArgb, 
    arrayHandle.AddrOfPinnedObject() 
); 

this.BackgroundImageLayout = ImageLayout.Stretch; 
this.BackgroundImage = bmp; 
+0

當我嘗試繪製newBitmap時,它會拋出Access Violation:/它說它應該從Paint方法(PaintEventArgs)中調用。 – zgnilec 2012-08-16 14:59:49

0

你不能只是使用:

System.Drawing.Bitmap.FromStream(new MemoryStream(bytes)); 

我不認爲這些方法調用會做任何複製,因爲沒有在MSDN中表示這樣:http://msdn.microsoft.com/en-us/library/9a84386f

+3

很多人似乎都錯過了這樣的事實,即FromStream方法期望流將包含位圖頭信息以及RGB或像素值。 – Mozzis 2015-03-20 01:23:28