DIB(デバイス独立ビットマップ)の作成

 Windows のビットマップには、通常のGDIで使われるデバイス依存ビットマップ(DDB)の他にもDIB(デバイス独立ビットマップ)というものがあります。これは、ピクセルの色を単純な配列としてまとめたビットマップで、プログラムの中で直接配列を使うのと同じような感じで(あるいは配列としても)扱う事が可能です。
 ただ、DIBに関する資料はなぜか非常に少ないのが現状なので、今回はいくつかの資料を基にとりあえずDIBを作って表示してみる事にしましょう。

・DIBの構造

 まず、今回はフルカラー(24ビット)のDIBを作ります。この時のビットマップは、1ピクセルが3バイト(上位から順にBGR)の構成です。ビットマップの本体は、このピクセルの情報が下から上、左から右の順に並んでいますが、これは通常のビットマップの構造とは上下逆なので注意してください。
 DIBを作る時は各ピクセルの色を格納したビットマップ本体の他に、ビットマップの大きさや色の形式などの情報を収めたBITMAPINFOHEADERとそのBITMAPINFOHEADER とパレットをまとめたBITMAPINFOという2つの構造体を作成する必要があります。最も、フルカラーではパレットは使いませんのでBITMAPINFOに入るのはBITMAPINFOHEADER だけですが。
 実際にDIBを扱う時には、BITMAPINFO構造体と各ピクセルの色の情報を格納したビットマップ本体へのポインタが必要になります。

BITMAPINFOHEADER 構造体のメンバ

biSize           構造体の大きさ(sizeof(BITMAPINFOHEADER))
biWidth          ビットマップの横幅
biHeight         ビットマップの高さ
biPlanes         ビットマップのプレーン
biBitCount       プレーンごとの色のビット数
biCompression    圧縮形式
biXPelsPerMeter  Y方向の解像度(ピクセル/m)
biYPelsPerMeter  X方向の解像度(ピクセル/m)
biClrUsed        使われている色数
biClrImporyant   重要な色

BITMAPINFO 構造体のメンバ

bmiHeader    BITMAPINFOHEADER 構造体
bmiColors    カラーパレット情報

 今回はフルカラーで圧縮したりもしませんのでBITMAPINFOHEADER構造体のbiCompression 以下は0(デフォルト)にしておきます。またプレーンは1にしてbiBitCountを24にすれば24ビットカラーが実現できますね。パレットは使用しないので、後はBITMAPINFObmiHeaderBITMAPINFOHEADER を設定するだけです。

 構造体の方ができたら次はピクセルの情報を格納するビットマップ本体のメモリを確保します。GlobalAllocで必要なだけ確保しましょう。例えば、作成するビットマップの大きさを64*64とすれば、必要なサイズは64*64*3バイト(24ビットは3バイト)ですね。返されるアドレスをバイト型ポインタにキャストして、

  lpBMP=(LPBYTE)GlobalAlloc(GPTR,64*64*3);

 としておきます。ただしこのバッファは、横方向1列の大きさを4の倍数にそろえる必要があるので注意してください。今回の例では、横64ドット/1ドット3バイトで横1列が192バイトになり、4の倍数なのでそのままで問題ありません。

 DIBの座標は、一番左下が原点(0、0)になっていますので、ビットマップの先頭アドレスをlpBMP、ビットマップの幅をdwWidthとすれば(x、y)のピクセルは以下のアドレスで参照出来ます。

  青成分 lpBMP+x*3+y*3*dwWidth
 緑成分 lpBMP+x*3+y*3*dwWidth+1
 赤成分 lpBMP+x*3+y*3*dwWidth+2

 例えば、64×64ピクセルのフルカラーDIBのビットマップ(lpBMP)をオレンジ色(RGB=255:128:0)で塗りつぶすなら以下のような感じです。

  for (i=0;i<64*64;i++) {

      lpBMP[i*3]=0;
      lpBMP[i*3+1]=128;
      lpBMP[i*3+2]=255;

  }

 作成したビットマップは、ウインドウのWM_PAINT メッセージを処理する時にStretchDIBitsでウインドウのデバイスコンテキストに描きます。

  case WM_PAINT:

      hdc=BeginPaint(hwnd,&ps);

      StretchDIBits(hdc,0,0,64,64,0,0,64,64,lpBMP,&BmInfo,
        DIB_RGB_COLORS,SRCCOPY);

      EndPaint(hwnd,&ps);

プログラムソース表示
戻る