问题描述
我在 HDD 上有几个 (~2GB) 原始 24bpp RGB 文件.现在我想检索它的一部分并将其缩放到所需的大小.
(唯一允许的比例是 1, 1/2, 1/4, 1/8, ..., 1/256)
I have several (~2GB) raw 24bpp RGB files on HDD.
Now I want to retrieve a portion of it and scale it to the desired size.
(The only scales allowed are 1, 1/2, 1/4, 1/8, ..., 1/256)
所以我目前正在将感兴趣的矩形中的每一行读取到一个数组中,这给我留下了一个高度正确但宽度错误的位图.
So I'm currently reading every line from the rectangle of interest into an array, which leaves me with a bitmap which has correct height but wrong width.
下一步,我将从新创建的数组中创建一个位图.
这是通过使用指针完成的,因此不涉及数据复制.
接下来我在 Bitmap 上调用 GetThumbnailImage,它会创建一个具有正确尺寸的新位图.
As the next step I'm creating a Bitmap from the newly created array.
This is done with by using a pointer so there is no copying of data involved.
Next I'm calling GetThumbnailImage on the Bitmap, which creates a new bitmap with the correct dimensions.
现在我想返回新创建的位图的原始像素数据(作为字节数组).但是为了实现这一点,我目前正在使用 LockBits 将数据复制到一个新数组中.
Now I want to return the raw pixel data (as a byte array) of the newly created bitmap. But to achieve that I'm currently copying the data using LockBits into a new array.
所以我的问题是:有没有办法在不复制的情况下将像素数据从位图中获取到字节数组中?
类似于:
var bitmapData = scaledBitmap.LockBits(...) byte[] rawBitmapData = (byte[])bitmapData.Scan0.ToPointer() scaledBitmap.UnlockBits(bitmapData) return rawBitmapData
我很清楚这行不通,这只是我想要实现的目标的一个例子.
I'm well aware that this doesn't work, it is just an example to what I basically want to achieve.
推荐答案
我认为这是您最好的选择.
I think this is your best bet.
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);
如果你想传递一个字节[],你必须复制它.
You have to copy it, if you want a pass around a byte[].
您不必删除已分配的字节,只需在完成后处理原始 Bitmap 对象,因为它实现了 IDisposable.
You don't have to delete the bytes that were allocated, you just need to Dispose of the original Bitmap object when done as it implements IDisposable.