C#中的倒像

时间:2011-02-24 06:16:01

标签: c# image

这是我从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;

        }

我有一个从上面提到的函数获取字节的函数,只是显示它而无需进一步处理。但是我在输出端得到了倒像。有人可以解释一下吗?

3 个答案:

答案 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。