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.Clone调用时不会制作像素数据的新副本,或者至少在您Bitmap使用自己分配的数据创建 a 时是这种情况。

相反,克隆似乎使用完全相同的像素数据,这对我来说是个问题,因为我在克隆操作后释放像素数据内存,导致克隆的位图在内存用于其他用途时损坏。

我发现的第一个也是当前的解决方案Bitmap.Clone是使用:

Bitmap clone = new Bitmap(bitmapToClone);

它确实将像素数据复制到其他地方,从而可以释放旧内存。

可能有更好/更快的方法来制作完全复制的克隆,但目前这是一个简单的解决方案。

于 2013-03-09T01:13:45.230 回答