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 に答える