1

我正在使用一个BitmapData对象来Bitmap.LockBits快速读取和写入像素数据。该功能被封装在一个类中。我可以将引用存储到对象的andScan0还是应该在每次需要访问像素时读取它?根据我的使用情况,同一个类对象可以活动几个小时,在这段时间内/会改变吗?或者我可以在类中存储对它们的引用以减少属性访问?StrideBitmapDataScan0Stride

每次访问(有点慢)

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
4

2 回答 2

2

不,位图的像素数据存储在非托管内存中。这就是 BitmapData.Scan0 的类型是 IntPtr 的原因。非托管指针永远不会改变它们的值,对于非托管堆管理器来说,没有类似的压缩垃圾收集器。

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

于 2013-03-08T15:21:52.500 回答
0

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

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

于 2013-03-08T14:33:39.810 回答