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);
}
}
この画像を、Photoshopで作成したピクセル(赤、緑、青、白)の非常に単純な2x2PNG画像でテストしました。形式のため、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に直接画像を使用すると、画像は正しく表示されます。それで私のせいは何ですか?
<Image Source="D:/tmp/test2.png"/>
ピクセルデータはARGB、アルファ用に1バイト、赤用に1、緑用に1、青用に1です。アルファは最上位バイトで、青は最下位バイトです。あなたや他の多くのようなリトルエンディアンのマシンでは、リトルエンドが最初に格納されるため、バイト順序はbb gg rraaになります。したがって、0 0 255255は青= 0、緑= 0、赤= 255、アルファ= 255に等しくなります。それは赤です。
整数もリトルエンディアンで格納されるため、bd.Scan0をint *(pointer-to-integer)にキャストすると、このエンディアン順の詳細は表示されなくなります。
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
を簡単に操作できます。
AFAIKは、技術的にはCOLORREF
(Windows GDI/GDI +で使用されています)に基づいており、RGBAをメモリに保存しています... http://msdn.Microsoft.com/en- us/library/dd183449%28VS.85%29.aspx