16ビットDIB

 今回は16ビットDIBを作ってみます。 1ピクセルを16ビットで表すので、216=65536 色を表せそうですが、実際には最上位1ビットは無視されRGBそれぞれ5ビット (計15ビット)で32768色になるようです。カラーテーブルは使わず (使おうと思えば使えるらしいが)、RGBを直接指定します。 1ピクセルに1ワード(16ビット)でアクセスできる上に、 カラーテーブルなしで実用上十分な色を使えますから(私も、WIndows の画面はいつも1024*768/16ビットカラーで使っています) けっこう便利かもしれませんね。

16ビットDIBを使う時はBITMAPINFOHEADERbiBitCount を16にして、 ビットマップの各ピクセルを1ワードで指定してください。 ビットマップ用に用意するメモリは、ピクセル数×2バイト (ピクセル数ワード)なので、 以下のように確保すれば良いでしょう。ただし、 幅が奇数ピクセルの時は横方向を4バイト単位にする必要があります。

  lpBuf=GlobalAlloc // 必要なメモリをまとめて確保
     (GPTR,sizeof(BITMAPINFO)+128*128*2);

  lpInfo=(LPBITMAPINFO)lpBuf; // メモリを分配
  lpBMP=(LPWORD)(lpBuf+sizeof(BITMAPINFO));

 次に、BITMAPINFO の設定です。

  lpInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
  lpInfo->bmiHeader.biWidth=128;
  lpInfo->bmiHeader.biHeight=128;
  lpInfo->bmiHeader.biPlanes=1;
  lpInfo->bmiHeader.biBitCount=16;
  lpInfo->bmiHeader.biCompression=BI_RGB;
  lpInfo->bmiHeader.biSizeImage=0;
  lpInfo->bmiHeader.biXPelsPerMeter=0;
  lpInfo->bmiHeader.biYPelsPerMeter=0;
  lpInfo->bmiHeader.biClrUsed=0;
  lpInfo->bmiHeader.biClrImportant=0;

 これで、 128*128ピクセルの16ビットDIBを使えるようになりました。
次に、 ビットマップに32(5ビット)段階のグレースケールを描いてみましょう。 これは各段階のグレースケールを、 それぞれ128*4ピクセルの長方形に描くプログラムです。

  for (i=0;i<32;i++) // 各ピクセルに色を付ける
    for (j=0;j<4;j++)
      for (k=0;k<128;k++)
        lpBMP[k+(j+i*4)*128]=(i << 10)+(i << 5)+i;

 各ピクセルは下位15ビットが上位から順に、 RGBそれぞれ5ビットになっているようです。 ですから赤成分は10ビット、緑成分は5ビット左シフトすれば良い事になります。 例えば、 グレースケールではなく赤成分を除いた水色のグラデーションにするには、

  for (i=0;i<32;i++) // 各ピクセルに色を付ける
    for (j=0;j<4;j++)
      for (k=0;k<128;k++)
        lpBMP[k+(j+i*4)*128]=(i << 5)+i;

 とします。

プログラムソース表示

戻る