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

我尝试从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); } } 

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

 255 255 0 0 255 0 255 0 255 0 0 255 255 255 255 255 

但我得到了:

 0 0 255 255 0 255 0 255 255 0 0 255 255 255 255 255 

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

  

像素数据为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。

AFAIK技术上基于COLORREF (在Windows GDI / GDI +中随处使用)并且将RGBA存储在内存中…请参阅http://msdn.microsoft.com/en-us/library/dd183449%28VS.85 %29.aspx

在Bpp32Argb像素格式。 你不需要逐字节访问。

在不安全的上下文中将Scan0转发到Int32指针。

 unsafe { var ptr=(int*)bmData.Scan0; } 

你可以像下面那样进行一些操作来访问第一个像素的颜色通道。

并且不需要关心字节顺序。

 var a=(ptr[0] & 0xFF000000)>>24; var r=(ptr[0] & 0x00FF0000)>>16; var g=(ptr[0] & 0x0000FF00)>>8; var b=(ptr[0] & 0x000000FF); 

顺便说一句,你可以使用Color.ToArgb()轻松返回int