我正在使用BitmapData
使用Bitmap.LockBits
获取的对象来快速读取和写入像素数据。该功能封装在一个类中。我可以将引用存储到Scan0
对象的Stride
和BitmapData
,还是应该在每次需要访问像素时读取它?根据我的用法,相同的类对象可以在小时中处于活动状态,在此期间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
答案 0 :(得分:2)
不,Bitmap的像素数据存储在非托管内存中。这就是为什么BitmapData.Scan0的类型是IntPtr。非托管指针永远不会改变它们的值,没有相当于非托管堆管理器的压缩垃圾收集器。
但是,只有位图被锁定时,这才有效。通常快速调用Bitmap.UnlockBits()非常重要。锁定有效时,位图对象不可用。在位图被锁定时,尝试执行绘制位图等操作将失败并出现异常。因此,存储Scan0指针以供以后使用几乎总是错误的。
答案 1 :(得分:0)
BitmapData
(因此Scan0
)的引用仅在您Bitmap.Lockbits
打开时有效,一旦您调用UnlockBits
指针不再有效。
您无法有效地缓存该值,但是如果您知道位图的颜色深度和大小不会改变,您可以预先计算一个查找表,该表将使用Stride删除大量用于访问像素位置的计算(行的宽度)和像素的大小(24bpp颜色深度为3个字节),因为它们基本上是静态的。