请问Bitmap.LockBits“针”位图到内存?(Does Bitmap.LockBits “p

2019-07-20 20:46发布

我使用的是锁定最近的位图很多,我不断收到“试图访问无效的内存”错误。 这主要是因为位图已经在内存中移动。 有些人使用GCHandle.Alloc()在CLR分配内存,它的引脚。 是否Bitmap.LockBits()一样吗? 我不明白“锁定”内存“钉住”内存之间的区别。 你也可以解释的术语,如果任何区别在哪里?

Answer 1:

GCHandle.Alloc是一个比较通用的方法,它允许你一个句柄分配给任何管理对象,并在内存别针把它(或没有)。 钉扎存储器防止GC从移动它,这是特别有用的,当你必须通过一些数据,例如阵列,一个非托管代码。

GCHandle.Alloc不会帮助你访问以任何方式位图的数据,因为这寄托对象将只是防止被管理对象从走动(位图对象)(和被收集的垃圾)。

然而,位图是周围的原生GDI +的包装BITMAP结构。 它不保留任何管理的阵列,你将不得不PIN数据,它只是管理的原生手柄GDI +位图对象。 正因为如此Bitmap.LockBits是告诉这个位图,你有兴趣在访问它的内存的一种方式,它只是周围的包装GdipBitmapLockBits功能。 所以你调用它需要有更多的事情要做,你是比与事实GDI +位图的工作,那你在托管环境中使用GC工作的事实。

一旦你已经使用LockBits你应该能够访问它的使用指针内存通过BitmapData.Scan0 -这是数据的第一个字节的地址。 你不应该有问题,只要,只要你不访问内存的背后BitmapData.Scan0 + Height * Stride

而rememberto UnlockBits当您完成。



Answer 2:

在你的情况下, attempted to access invalid memory错误很可能是无效的内存分配,你在代码的不安全部分做的,比如分配的数组比你正试图把在像素数较小造成的。

也没有必要去想,除非你的图像数据是固定对象小于85000个字节的对象只小于85K将在内存中移动。

如果您传递对象非托管代码,例如在C ++库,用于更快的处理另一个故事会。 在这种情况下,您的例外是很可能的,如果通过图像失控的范围,将垃圾收集。 在这种情况下,你可以使用GCHandle.Alloc (imageArray,GCHandleType.Pinned); 比拨打免费电话,如果你不需要它的任何更长的时间。



文章来源: Does Bitmap.LockBits “pin” a bitmap into memory?