2009年9月19日土曜日

ImageLockMode.UserInputBuffer | ImageLockMode.WriteOnly

データからBitmapの生成をよくするんですが、だいたいこんなコードを書きます。

byte[] pixels;

var bitmap = new Bitmap( width, height, PixelFormat.Format32bppArgb );
var data = bitmap.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb );
Marshal.Copy( pixels, 0, data.Scan0, pixels.Length );
bitmap.UnlockBits( data );
Marshal.Copy()が無駄に思えたのでImageLockMode.UserInputBufferを使ってみました。するとこんな風に書き換わります。
byte[] pixels;

var bitmap = new Bitmap( width, height, PixelFormat.Format32bppArgb );
bar handle = GCHandle.Alloc( pixcels, GCHandleType.Pinned );
try{
var data = new BitmapData{
PixelFormat = PixelFormat.Format32bppArgb,
Width = width,
Height = height,
Stride = stride,
Scan0 = Marshal.UnsafeAddrOfPinnedArrayElement( pixels, 0 ),
};
bitmap.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.UserInputBuffer|ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb, data );
bitmap.UnlockBits( data );
}
finally{
handle.Free();
}
無駄なコピーが排除できた! と喜んだものの、処理がかなり遅くなりました…。GCHandle.Alloc()のせいではなく、ImageLockMode.UserInputBufferが原因のようです。

0 件のコメント: