C#画像処理

【C#】Bitmap画像データのメモリ構造

Bitmap画像の輝度値を参照するには、こちらのページ↓

【C#】Bitmap画像の輝度値の参照設定
画像の輝度値(画素値)を取得/設定するのに、.NETでは SetPixel と GetPixel というメソッドが用意されていますが、処理が遅かったり、モノクロの8ビット画像でSetPixelを実行しようとすると 型 'System.Inv...

 

で、Bitmap画像のメモリの値を参照するにはBitmapオブジェクトをLockBitsでロックし、BitmapDataScan0プロパティを参照すれば、良いと書きましたが、この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画素の画像を例にとって説明します。

Bitmap Data Memory Format

 

上図のように3x3の画像であってもメモリ上は下図のように一列にデータが並んでおり、BitmapDataのSacn0がメモリの先頭アドレスを差しています。

Bitmap Data Memory Format

 

上図は8ビットのモノクロ画像の場合ですが、1行あたりのメモリサイズが4の倍数のバイトになるように余計にメモリが追加(上図のグレーの部分)されいます。

 

この1行あたりのメモリのサイズはBitmapDataStrideプロパティで取得できますが、自分で計算すると

 

stride = (width * bitCount + 31) / 32 * 4;

 

という計算で求めることができ、幅が3画素、8ビットの場合は

Bitmap Data Memory Format

 

24ビットカラーの場合は、1画素あたり3バイト、メモリを使用し、画像の左上からB,G,R,B,G,R,・・・の順番でメモリに画像の輝度値が格納され

Bitmap Data Memory Format

 

のようになっています。

同様に32ビットの場合は、1画素あたり4バイト、メモリを使用し、画像の左上からB,G,R,A,B,G,R,A,・・・の順番でメモリに画像の輝度値が格納され

Bitmap Data Memory Format

 

となり、32ビットの場合は1画素あたり4バイトなので、画像の幅の画素数に関係なく余計なメモリが追加されることはありません。

 

画像を表示して斜めに表示される場合は、このStrideあたり(メモリの確保や輝度値の参照方法)がおかしい場合が多いので、確認してみて下さい。

 

参考までに、ビットマップファイル(*.bmp)の画像データ部分は、幅方向については、上記の通りですが、画像の左下から上へ(ボトムアップ)メモリに格納されています。

 

画像処理のためのC#テクニックへ戻る

コメント

タイトルとURLをコピーしました