BitmapData的Scan0或Stride可以在一段时间内发生变化吗?

时间:2013-03-08 14:24:38

标签: image performance image-processing bitmapdata reliability

我正在使用BitmapData使用Bitmap.LockBits获取的对象来快速读取和写入像素数据。该功能封装在一个类中。我可以将引用存储到Scan0对象的StrideBitmapData,还是应该在每次需要访问像素时读取它?根据我的用法,相同的类对象可以在小时中处于活动状态,在此期间Scan0 / Stride会发生变化吗?或者我可以在类中存储refs以减少属性访问吗?

每次访问(稍慢)

public BitmapData Data;

byte* pixByte = (byte*)BmpData.Scan0 + (Y * BmpData.Stride) + (X * 3); // access pixel of 24bpp image

存储参考(这可能吗?)

public BitmapData Data;
public IntPtr Scan0;
public int Stride;

byte* pixByte = (byte*)Scan0 + (Y * Stride) + (X * 3); // access pixel of 24bpp image

2 个答案:

答案 0 :(得分:2)

不,Bitmap的像素数据存储在非托管内存中。这就是为什么BitmapData.Scan0的类型是IntPtr。非托管指针永远不会改变它们的值,没有相当于非托管堆管理器的压缩垃圾收集器。

但是,只有位图被锁定时,这才有效。通常快速调用Bitmap.UnlockBits()非常重要。锁定有效时,位图对象不可用。在位图被锁定时,尝试执行绘制位图等操作将失败并出现异常。因此,存储Scan0指针以供以后使用几乎总是错误的。

答案 1 :(得分:0)

BitmapData(因此Scan0)的引用仅在您Bitmap.Lockbits打开时有效,一旦您调用UnlockBits指针不再有效。

您无法有效地缓存该值,但是如果您知道位图的颜色深度和大小不会改变,您可以预先计算一个查找表,该表将使用Stride删除大量用于访问像素位置的计算(行的宽度)和像素的大小(24bpp颜色深度为3个字节),因为它们基本上是静态的。