Bitmap画像の輝度値を参照するには、こちらのページ↓
で、Bitmap画像のメモリの値を参照するにはBitmapオブジェクトをLockBitsでロックし、BitmapDataのScan0プロパティを参照すれば、良いと書きましたが、このScan0で示されたメモリの構造のお話です。
C言語で画像の表示を行った事がある人には、WindowsのDIB(Device Independent Bitmaps)の画像データの構造とほぼ同じで、データの並びがトップダウンになります。
で済むのですが、私自身もC言語で画像の表示をすることは少なくなり、これで通じる人は少なくなった気がします。。
簡単に画像データのメモリ構造を説明すると
●画像の左上から順にメモリに配置されている(トップダウン)
●画像1行あたりのメモリは4の倍数のバイトになるように調整されている
●カラーの場合、B,G,R,B,G,R,・・・もしくは B,G,R,A,B,G,R,A,・・・の順で並んでいる
より具体的に3x3画素の画像を例にとって説明します。
上図のように3x3の画像であってもメモリ上は下図のように一列にデータが並んでおり、BitmapDataのSacn0がメモリの先頭アドレスを差しています。
上図は8ビットのモノクロ画像の場合ですが、1行あたりのメモリサイズが4の倍数のバイトになるように余計にメモリが追加(上図のグレーの部分)されいます。
この1行あたりのメモリのサイズはBitmapDataのStrideプロパティで取得できますが、自分で計算すると
stride = (width * bitCount + 31) / 32 * 4;
という計算で求めることができ、幅が3画素、8ビットの場合は
24ビットカラーの場合は、1画素あたり3バイト、メモリを使用し、画像の左上からB,G,R,B,G,R,・・・の順番でメモリに画像の輝度値が格納され
のようになっています。
同様に32ビットの場合は、1画素あたり4バイト、メモリを使用し、画像の左上からB,G,R,A,B,G,R,A,・・・の順番でメモリに画像の輝度値が格納され
となり、32ビットの場合は1画素あたり4バイトなので、画像の幅の画素数に関係なく余計なメモリが追加されることはありません。
画像を表示して斜めに表示される場合は、このStrideあたり(メモリの確保や輝度値の参照方法)がおかしい場合が多いので、確認してみて下さい。
参考までに、ビットマップファイル(*.bmp)の画像データ部分は、幅方向については、上記の通りですが、画像の左下から上へ(ボトムアップ)メモリに格納されています。
←画像処理のためのC#テクニックへ戻る
コメント