在Java中我会做这样的事情
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
其中image是BufferedImage,然后改变那里的像素并制作我自己的blitting方法但是我应该如何在C#中做这样的事情?我知道我可以使用Bitmap替换C#中的BufferedImage,但我不确定如上所示引用数据。
答案 0 :(得分:7)
您可以使用Lockbits
和Marshal.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)