PixelFormat.Format32bppArgb似乎有错误的字节顺序

0xB*_*00D 23 .net c# bitmap bitmapdata

我尝试从Bitmap(System.Drawing.Bitmap)获取所有字节值.因此我锁定字节并复制它们:

public static byte[] GetPixels(Bitmap bitmap){
    if(bitmap-PixelFormat.Equals(PixelFormat.Format32.bppArgb)){
        var argbData = new byte[bitmap.Width*bitmap.Height*4];
        var bd = bitmap.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
        System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, argbData, 0, bitmap.Width * bitmap.Height * 4);
        bitmap.UnlockBits(bd);
    }
}
Run Code Online (Sandbox Code Playgroud)

我用一个非常简单的2x2 PNG图像测试了这个图像,这个图像是我在Photoshop中创建的像素(红色,绿色,蓝色,白色).由于格式,我期望argbData中的以下值:

255 255   0   0    255 0   255   0 
255 0     0 255    255 255 255 255 
Run Code Online (Sandbox Code Playgroud)

但我得到了:

0     0 255 255     0 255   0 255
255   0   0 255   255 255 255 255
Run Code Online (Sandbox Code Playgroud)

但这是一种BGRA格式.有人知道为什么字节似乎被交换了吗?顺便说一句,当我直接将图像用于Image.Source时,如下所示,图像显示正确.那我的错是什么?

<Image Source="D:/tmp/test2.png"/>
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 40

像素数据为ARGB,1字节表示alpha,1表示红色,1表示绿色,1表示蓝色.Alpha是最重要的字节,蓝色是最不重要的字节.在像您和其他许多人一样的小端机器上,首先存储小端,因此字节顺序为bb gg rr aa.所以0 0 255 255等于蓝色= 0,绿色= 0,红色= 255,alpha = 255.那是红色.

当你将bd.Scan0转换为int*(指向整数的指针)时,这个字节顺序细节会消失,因为整数也存储为little-endian.

  • 外观极好!我只能补充一点,您可以通过[BitConverter.IsLittleEndian]检查数据存储在此计算机体系结构中的字节顺序("endianness")(http://msdn.microsoft.com/en-us/library/system .bitconverter.islittleendian.aspx)字段. (5认同)
  • 这是关于`BitConverter.IsLittleEndian` 的一个很好的观点,但我认为@HansPassant 关于字节序的评论非常有价值——这是另一个**不**考虑字节序的地方。[这里是](http://commandcenter.blogspot.com.au/2012/04/byte-order-fallacy.html) 一篇关于这个主题的好文章.. (2认同)