2

我正在尝试使用 BitmapData 类?并且在将 IntPtr 值分配给 BitmapData.Scan0 属性时遇到一些问题。这是我的代码:

var data = bmp.LockBits(new rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
data.Scan0 = rh.data.Scan0HGlobal;
bmp.UnlockBits(data);

但是,解锁图像后,它不会改变。为什么?在调试模式下,我看到 data.Scan0 更改为 rh.data.Scan0HGlobal 值。在 rh.data.Scan0HGlobal 我有指向内存的指针,其中包含像素的原始数据。

4

2 回答 2

4

好吧,Scan0 属性设置器不是私有的,这有点令人遗憾。但是,是的,这没有任何作用。您需要自己复制字节以更改图像。使用 Marshal.Copy() 通过 pinvoke memcpy() 的 byte[] 辅助数组进行复制。

于 2012-08-21T18:56:35.720 回答
1

这是你应该如何做的:

// Lock image bits.
// Also note that you probably should be using bmp.PixelFormat instead of
// PixelFormat.Format32bppArgb (if you are not sure what the image pixel
// format is).
var bmpData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size),
    ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

// This is total number of bytes in bmp.
int byteCount = bmpData.Stride * bmp.Height;
// And this is where image data will be stored.
byte[] rgbData = new byte[byteCount];

// Copy bytes from image to temporary byte array rgbData.
System.Runtime.InteropServices.Marshal.Copy(
    bmpData.Scan0, rgbData, 0, byteCount);    

// TODO: Work with image data (now in rgbData), perform calculations,
// set bytes, etc.
// If this operation is time consuming, perhaps you should unlock bits
// before doing it.
// Do remember that you have to lock them again before copying data
// back to the image.

// Copy bytes from rgbData back to the image.
System.Runtime.InteropServices.Marshal.Copy(
   rgbData, 0, bmpData.Scan0, byteCount);
// Unlock image bits.
image.UnlockBits(bmpData);

// Save modified image, or do whatever you want with it.

希望能帮助到你!

于 2012-08-21T19:10:21.350 回答