我需要创建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
显示它时,整个程序崩溃 - 无论是一个还是另一个,完全随机。
答案 0 :(得分:1)
内存损坏的原因是因为我在使用Bitmap.Clone
后使用_bitmapObject
复制了FastBitmap
。
Bitmap.Clone
在调用时不会生成像素数据的新副本,或者至少在使用您自己的已分配数据创建Bitmap
时就是这种情况。
相反,克隆似乎使用完全相同的像素数据,这对我来说是有问题的,因为我在克隆操作后释放像素数据内存,导致克隆的位图在内存用于其他事情时损坏。 / p>
我发现作为Bitmap.Clone
的替代方案的第一个和当前的解决方案是使用:
Bitmap clone = new Bitmap(bitmapToClone);
将像素数据复制到其他地方,这样可以释放旧内存。
可能有更好/更快的方法来制作完全复制的克隆,但现在这是一个简单的解决方案。