2012-11-07 100 views
3

在Java中,我會做這樣的事存儲位圖的數據位爲int數組

int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); 

,其中圖像是一個BufferedImage,然後改變那裏的像素,讓我自己的blitting方法,不過爲什麼我應該在C#中做這樣的事情?我知道我可以使用位圖來替換C#中的BufferedImage,但我不確定如何使用上面所示的數據。

回答

7

你會使用LockbitsMarshal.Copy

Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
System.Drawing.Imaging.BitmapData bmpData = 
    bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); 

IntPtr ptr = bmpData.Scan0; 
int bytes = Math.Abs(bmpData.Stride) * bmp.Height; 
byte[] rgbValues = new byte[bytes]; 

// Copy the RGB values into the array. 
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); 

// do something with the array 

// Copy the RGB values back to the bitmap 
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 

bmp.UnlockBits(bmpData); 

注:該代碼基本上是從LockBits文檔頁面的示例代碼,但是代碼有一個限制。它假設Stride值爲正數,即圖像沒有上下顛倒存儲在內存中,儘管在Stride值上使用Math.Abs表示編寫代碼的人知道Stride值可能是負值。

對於負值Stride值,Scan0不能用作連續存儲器塊的起始地址,因爲它是第一條掃描線的地址。內存塊的起始地址將是圖像中最後一行的起始地址,而不是第一個地址。

該地址將是bmpData.Scan0 + bmpData.Stride * (bmp.Height - 1)