3

在Java中我会做这样的事情

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

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

4

1 回答 1

7

您将使用Lockbitsand 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.AbsonStride值表明编写代码的人知道该Stride值可能为负。

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

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

于 2012-11-07T16:20:14.043 回答