将位图的数据位存储到int数组中

时间:2012-11-07 16:13:14

标签: c# bitmap

在Java中我会做这样的事情

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

其中image是BufferedImage,然后改变那里的像素并制作我自己的blitting方法但是我应该如何在C#中做这样的事情?我知道我可以使用Bitmap替换C#中的BufferedImage,但我不确定如上所示引用数据。

1 个答案:

答案 0 :(得分: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值为正,即图像不是倒置存储在内存中,尽管在Math.Abs值上使用Stride表示编写代码的人是意识到Stride值可能是负数。

对于负Stride值,Scan0不能用作连续内存块的起始地址,因为它是第一条扫描线的地址。内存块的起始地址将是图像中最后一行的起始地址,而不是第一行的起始地址。

该地址为bmpData.Scan0 + bmpData.Stride * (bmp.Height - 1)