3

Javaでは、私はこのようなことをします

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

ここで、画像は BufferedImage であり、そこのピクセルを変更して独自のブリッティング メソッドを作成しますが、C# でこのようなことを行うにはどうすればよいですか? Bitmap を使用して C# の BufferedImage を置き換えることができることはわかっていますが、上記のようなデータへの参照を作成するかどうかはわかりません。

4

1 に答える 1

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.Abson を使用するとStride、コードを書いている人がStride値が負になる可能性があることを認識していたことが示されます。

Strideの値の場合Scan0、最初のスキャン ラインのアドレスであるため、連続メモリ ブロックの開始アドレスとして使用することはできません。メモリ ブロックの開始アドレスは、イメージの最初の行ではなく、最後の行の開始アドレスになります。

その住所はbmpData.Scan0 + bmpData.Stride * (bmp.Height - 1)

于 2012-11-07T16:20:14.043 に答える