从System.Drawing.Bitmap高效地获取像素数据的C#方法

15
我有几个(~2GB) 原始的24bpp RGB文件在硬盘上。 现在我想获取其中一部分并将其按所需大小缩放。(允许的比例只有1、1/2、1/4、1/8、…、1/256)
目前,我正在将感兴趣的矩形中的每一行读入数组中,这会留下一个具有正确高度但错误宽度的位图。
接下来,我使用指针从新创建的数组创建一个Bitmap。这是通过指针完成的,因此不涉及数据的复制。接下来,我调用Bitmap的GetThumbnailImage方法,创建具有正确尺寸的新位图。
现在我想将新创建的位图的原始像素数据作为字节数组返回。但是要实现这一点,我目前正在使用LockBits将数据复制到新的数组中。
所以我的问题是: 是否有一种方法可以将 Bitmap 的像素数据直接放到一个字节数组中而不需要复制它?
例如:
var bitmapData = scaledBitmap.LockBits(...)
byte[] rawBitmapData = (byte[])bitmapData.Scan0.ToPointer()
scaledBitmap.UnlockBits(bitmapData)
return rawBitmapData 
我非常清楚这不起作用,这只是一个基本想法的示例。

尝试使用IntPtr ptr = bitmapData.Scan0; int bytes = Math.Abs(bitmapData.Stride) * bitmapData.Height; raw = new byte[bytes]; Marshal.Copy(ptr, raw, 0, bytes);代替unsafe{} void* to byte[],以便工作。返回raw; // byte[] - antonio
1个回答

23

我认为这是你最好的选择。

var bitmapData = scaledBitmap.LockBits(...);
var length = bitmapData.Stride * bitmapData.Height;

byte[] bytes = new byte[length];

// Copy bitmap to byte[]
Marshal.Copy(bitmapData.Scan0, bytes, 0, length);
scaledBitmap.UnlockBits(bitmapData);

如果你想要在字节数组之间传递,那么你需要复制它。

你不需要删除已分配的字节,只需在完成后处理原始的Bitmap对象,因为它实现了IDisposable。


虽然不是我期望的答案,但使用Marshal.Copy使得复制整数变得更加美观。谢谢。 - Arokh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接