0

Bitmapピクセル データに直接アクセスできるオブジェクトを作成する必要があります。

LockBits私のニーズには遅すぎます-(時には大きい)ビットマップを迅速に再作成するには適していません。

だから私はカスタムFastBitmapオブジェクトを持っています。Bitmapオブジェクトへの参照とIntPtr、ビットマップ内のビットを指す があります。

コンストラクタは次のようになります。

public FastBitmap(int width, int height)
{
    unsafe
    {
        int pixelSize = Image.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8;
        _stride = width * pixelSize;

        int byteCount = _stride * height;

        _bits = Marshal.AllocHGlobal(byteCount);

        // Fill image with red for testing
        for (int i = 0; i < byteCount; i += 4)
        {
            byte* pixel = ((byte *)_bits) + i;
            pixel[0] = 0;
            pixel[1] = 0;
            pixel[2] = 255;
            pixel[3] = 255;

        }

        _bitmapObject = new Bitmap(width, height, _stride, PixelFormat.Format32bppArgb, _bits); // All bits in this bitmap are now directly modifiable without LockBits. 

    }
}

割り当てられたメモリは、デコンストラクタによって呼び出されるクリーンアップ関数で解放されます。

これは機能しますが、長くは続きません。どういうわけか、ビットをさらに変更しないと、割り当てられたメモリが破損し、ビットマップが破損します。Graphics.DrawImage場合によっては、ビットマップの大部分がランダムなピクセルに置き換えられたり、完全にランダムに表示しようとするとプログラム全体がクラッシュしたりすることがあります。

4

1 に答える 1

1

メモリが壊れていたBitmap.Clone_bitmapObjectは、FastBitmap.

Bitmap.CloneBitmapは、呼び出されたときにピクセル データの新しいコピーを作成しません。少なくとも、独自に割り当てられたデータを使用して を作成する場合はそうです。

代わりに、複製はまったく同じピクセル データを使用しているように見えます。これは、複製操作の後にピクセル データ メモリを解放していたため、メモリが他の目的に使用されたときに複製されたビットマップが破損したため、問題がありました。

代替手段として私が見つけた最初の現在の解決策Bitmap.Cloneは、次を使用することです。

Bitmap clone = new Bitmap(bitmapToClone);

これにより、ピクセル データが別の場所にコピーされるため、古いメモリを解放しても問題ありません。

完全にコピーされたクローンを作成するためのより良い/より高速な方法があるかもしれませんが、これは今のところ単純な解決策です。

于 2013-03-09T01:13:45.230 に答える