CreateDIBitmap

CreateDIBitmapは、DIBからDDBを作成するWindowsAPI・・・。

CreateDIBitmap 関数
DIB→DDB変換【Windowsプログラミング研究所】

これまでビットマップは、LoadImageでロードし、取得したビットマップハンドルをSelectObjectでデバイスコンテキストに選択させ、転送先デバイスコンテキストにBitBltで転送するといった流れだった・・・。

ビットマップハンドルを選択したデバイスコンテキストを使って、グラフィック操作をするビットマップを、DDB(デバイス依存ビットマップ)と呼ぶ・・・。
デバイスコンテキストハンドルを渡せば、比較的簡単に画像処理をしてくれる関数がいくつもある・・・。(BitBltやRectangleなど)
一方、ピクセルデータ列を保持し、デバイスに依存しないビットマップを、DIB(デバイス独立ビットマップ)と呼ぶ・・・。
こちらは1ピクセルごとに処理できる自由度の高さの反面、ピクセル列のメモリを保持する必要があるし、DDBで扱える画像処理関数の処理は自前でやらなければならない・・・。

実は、ビットマップファイルそのものはDIB形式のデータをファイルに保存されたものなのである・・・。
なので、ビットマップファイルを読み込み、DIB形式に沿って解析し、CreateDIBitmapを使ってDDBに変換すれば、BitBltなどのDDB用の関数で表示することができる・・・。

test.bmpDDBに変換して、ウィンドウ上に表示する・・・。

これらのスタティック変数を用意しておく・・・。

さらに、WM_CREATEでこれらのローカル変数も宣言しておく・・・。

ウィンドウのデバイスコンテキスト、バックバッファ用のビットマップ用意・・・。
(ダブルバッファリングにするので・・・。)

test.bmpのファイルサイズ取得・・・。

DIBはBITMAPFILEHEADERから始まるので、この部分のデータだけ読み込んでbfhに格納・・・。
次にBITMAPINFOHEADERの分だけ読み込んでbiに格納・・・。

bfh.bfOffBitsは、ピクセル列がファイルの先頭から何バイト目にあるかを指しているので、全体のサイズdwSizeからbfh.bfOffBitsを引くと、ピクセル列のサイズがわかる・・・。
なのでその分のメモリをnewで確保・・・。

ピクセル列を読み込んで、

CreateDIBitmapにピクセル列lpBitsPixelとbiやbi.bmiHeaderのアドレスを渡すと、変換後のDDBのハンドルhDDBが返される・・・。

バックバッファ用ビットマップはバックバッファ用のメモリデバイスコンテキストに、変換後のDDBDDB用のメモリデバイスコンテキストに選択させる・・・。

WM_DESTROYの時は、

それぞれのビットマップ、デバイスコンテキストの削除など・・・。
ピクセル列lpBitsPixelも削除・・・。

WM_PAINTで先程のDDBをバックバッファに転送、バックバッファをウィンドウにさらに転送というダブルバッファリング・・・。

さて、実行してtest.bmpを読み込んで表示できるかどうか・・・。

f:id:BG1:20151127233528p:plain

左が今回のプログラムが表示している画像、右がtest.bmpをイメージビューアで開いたもの・・・。
ちゃんと表示されてる・・・。

Sample/CreateDIBitmap.cpp at master · bg1bgst333/Sample · GitHub