ソフトウェア開発 Win32プログラミング

ビットマップのイメージを取得・書き換えする

戻る


ビットマップは、DIB(device independent bitmap)とDDB(device dependent bitmap) に分類される。CreateDIBSectionで作られたビットマップや LR_CREATEDIBSECTIONフラグを付けてLoadImageで読み込まれたビットマップは、 DIBであり、単純にLoadBitmapで読み込まれたビットマップは、DDBである。

さらにDIBは使用可能な最大色数、もしくはビットの深さ(単位はbpp; bits per pixel)により 分類できる(ピクセル(pixel)は色の付いた2次元平面上の点を意味する)。 ビットの深さは、1、4、8、16、24、32のいずれかである(16bppは複雑なため、 サポートしないことが多い)。

与えられたハンドルのビットマップがDIBかどうかは、GetObject関数で知ることができる。

DIBSECTION ds;
if (GetObject(hbm, sizeof(DIBSECTION), &ds))
{
    // hbmはDIBである。ここで
    // ds.dsBm.bmBitsは、ビットマップのイメージである。
}
else
{
    // hbmはDDBである。
}

DIBならばこれにより、直接書き換えが可能なビットマップのイメージを取得できる。

ビットの深さは、次のようなコードで取得できる。

BITMAP bm;
GetObject(hbm, sizeof(BITMAP), &bm);
// bm.bmBitsPixelがビットの深さ。

ビットマップのイメージは、同じサイズの複数のスキャンラインの並びである。 スキャンラインは、ピクセルデータの並びとそれに続く4バイト配置のための詰め物である。 詰め物は、0バイト以上で、スキャンラインが4の倍数になるようなサイズである。 詰め物を合わせたスキャンラインのサイズを得るには、 GetObject(hbm, sizeof(BITMAP), &bm)のbm.bmWidthBytesを得るか、 次のようなWIDTHBYTESマクロを使うとよい。

#define WIDTHBYTES(bitsperline) (((bitsperline) + 31) / 32 * 4)

ここでbitsperlineは、スキャンラインあたりの有効なピクセルデータのサイズであり、 これはBPPとビットマップの幅の乗算で求めることができる。 なお、ビットマップのイメージのことを単にbitsと呼ぶことができる。 また、詰め物以外のピクセルデータの並びをbitmap arrayと呼ぶことがある。

DIBでなくても、ビットマップはGetDIBits・SetDIBits関数により、 デバイスに依存しないbitsを取得・設定することができる。 GetDIBitsを呼ぶ前には、 上述のWIDTHBYTESマクロなどでサイズを計算したbitsの格納先バッファをあらかじめmallocなどで用意する必要がある。 GetDIBits・SetDIBitsで取得・設定するbitsの形式は、BITMAPINFO構造体で指定する。

詳しくは、BITMAPINFO構造体とBITMAPINFOHEADER構造体のヘルプを見ること。


戻る

©片山博文MZ
katayama.hirofumi.mz@gmail.com

inserted by FC2 system