Win32 Programming Memo: デバイス独立ビットマップ

(c) Copyright 2003 by Hirofumi Fujii
(LastUpdate:10-Dec-2003)
(FirstDraft:06-Nov-2003)

デバイス独立ビットマップ(Device Independent Bitmap)を表示することを 考える。使用する関数は SetDIBitsToDevice() である。 Win32 SDK でこの関数の引数は以下のように定義されている。

int SetDIBitsToDevice
(
  HDC hdc,
  int XDest, int YDest,
  DWORD dwWidth, DWORD dwHeight,
  int XSrc, int YSrc,
  UINT uStartScan, UINT uScanLines,
  CONST VOID *lpvBits, CONST BITMAPINFO *lpbmi,
  UINT fuColorUse
)

ここで、問題になるのは実際の画像データである lpvBits と、その 形式を指定している lpbmi である。lpvBits のデータは、lpbmi の 指定により、1 pixel あたりのビット数が決まり、かつ、この bit 配列はパックされて格納される。一方、各 scan line は LONG 境界で終了していなければならず、もし余りの bit があれば 0 で padding する。これらの点は、他の形式の画像データを変換 する時には特に注意を要する。


bmp ファイル

bmp ファイルを上記関数を使って表示することは(フルカラーの 表示ができるデバイスを使うのであれば)比較的簡単である。 単にファイルデータを全部メモリーに読み込んで、上記関数の引数に 合うようにポインタを設定して、呼び出せばよい。つまり、データ のファイル中での格納形式を知ればよい。

Win32 SDK によれば、bmp ファイルの構造は以下のようである (ここでは、OS/2 の bmp ファイル形式は除く)。

  BITMAPFILEHEADER
  BITMAPINFO
    BITMAPINFOHEADER
    RGBQUAD
       :
  bitmap data

ここで、bitmap data の位置(lpvBits) は BITMAPFILEHAEDER の中の bfOffBits で指定される。


拡大・縮小

デバイス独立ビットマップを表示するもう一つの関数に、 StretchDIBits() がある。これは、元の画像を 拡大・縮小する機能付きの表示関数であり、窓枠に合わせて 表示する時などに便利な関数である。規定値のモードで 使うと、若干情けない(その代わり速い)画像表示になる。 処理に多少時間がかかってもよいのであれば、前もって SetStretchBltMode()HALFTONE を指定 しておく。


減色

256色以下のデバイスに対しては、減色してパレット表示する必要がある。 これを実現するには、

という手続きが必要になる。