这是我从here收集的代码。
private unsafe byte[] BmpToBytes_Unsafe(Bitmap bmp)
{
BitmapData bData = bmp.LockBits(new Rectangle(0,0,1000,1000),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
// number of bytes in the bitmap
int byteCount = bData.Stride * bmp.Height;
byte[] bmpBytes = new byte[byteCount];
// Copy the locked bytes from memory
Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);
Marshal.
// don't forget to unlock the bitmap!!
bmp.UnlockBits(bData);
return bmpBytes;
}
我有一个从上面提到的函数获取字节的函数,只是显示它而无需进一步处理。但是我在输出端得到了倒像。有人可以解释一下吗?
答案 0 :(得分:1)
这是正常的,位图是颠倒存储的。底部扫描线位于BitmapData.Scan0。你需要纠正这个问题,可能是一次复制一条扫描线。取决于你如何显示它。
答案 1 :(得分:1)
当你说“倒”时,我想你的意思是倒置?
您不能依赖发布该代码的人的“l33t hax0r skillz”。他缺乏关于如何在内存中处理位图的重要信息。
当您从位图中读取数据时,您无法在一个块中读取所有数据。数据存储在行中,并且行可以首先存储在顶行中,或者首先存储在底行中。此外,线之间可能存在填充,以使每条线都在偶数字边界上。
Scan0
属性是指向第一行开头的指针,Stride
属性是指向下一行开头的偏移量。 Width
属性可用于确定每行中的数据量。
因此,您必须一次复制一行数据:
int lineSize = bData.Width * 3;
int byteCount = lineSize * bData.Height;
byte[] bmpBytes = new byte[byteCount];
IntPtr scan = bData.Scan0;
for (int i = 0; i < bData.Height; i++) {
Marshal.Copy(scan, bmpBytes[i * lineSize], 0, lineSize);
scan += bData.Stride;
}
答案 2 :(得分:0)
24 bpp windows位图内部保持BGR顺序的像素颜色,而不是RGB。