问题
I try to get all byte values from a Bitmap(System.Drawing.Bitmap). Therefore I lock the bytes and copy them:
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);
}
}
I tested this Image with a very simple 2x2 PNG image with pixels (red, green, blue, white) that I created in Photoshop. Because of the format, I expected the following values within the argbData:
255 255 0 0 255 0 255 0
255 0 0 255 255 255 255 255
But I got:
0 0 255 255 0 255 0 255
255 0 0 255 255 255 255 255
But this is a BGRA format. Does anybody know why the bytes seems swapped? By the way, when I use the image directly for a Image.Source as shown below, the Image is shown correctly. So what's my fault?
<Image Source="D:/tmp/test2.png"/>
回答1:
Pixel data is ARGB, 1 byte for alpha, 1 for red, 1 for green, 1 for blue. Alpha is the most significant byte, blue is the least significant. On a little-endian machine, like yours and many others, the little end is stored first so the byte order is bb gg rr aa. So 0 0 255 255 equals blue = 0, green = 0, red = 255, alpha = 255. That's red.
This endian-ness order detail disappears when you cast bd.Scan0 to an int* (pointer-to-integer) since integers are stored little-endian as well.
回答2:
In Bpp32Argb pixel format. You dont' need to byte-by-byte access.
Trun Scan0 to an Int32 pointer in unsafe context.
unsafe
{
var ptr=(int*)bmData.Scan0;
}
You can do some bit operation like below To access color channels of first pixel.
And dont need to care byte-order.
var a=(ptr[0] & 0xFF000000)>>24;
var r=(ptr[0] & 0x00FF0000)>>16;
var g=(ptr[0] & 0x0000FF00)>>8;
var b=(ptr[0] & 0x000000FF);
BTW you can work with Color.ToArgb()
returned int
easily.
回答3:
AFAIK it is technically based on COLORREF
(which is used in Windows GDI/GDI+ everywhere) and that is stored RGBA in memory... see http://msdn.microsoft.com/en-us/library/dd183449%28VS.85%29.aspx
来源:https://stackoverflow.com/questions/8104461/pixelformat-format32bppargb-seems-to-have-wrong-byte-order