デバイス・コンテキストからDIB(デバイス非依存ビットマップ)を取得するには,必要なメモリを確保した上でヘッダを設定し,GetDIBits
関数を呼び出す.
(実際には,デバイス・コンテキストから直接ではなく,BITMAP
オブジェクトから取得する)
ここでは,24bitカラーのDIBを取得する方法を示す.
GetDIBits
関数に渡すヘッダは,
BITMAPINFO
構造体であるが,カラー・マスクを使用しない場合にはBITMAPINFOHEADER
構造体で代用できる.(型キャストが必要)
LPBITMAPINFOHEADER lpdibh;
lpdibh->biSize = sizeof(BITMAPINFOHEADER);
lpdibh->biWidth = WIDTH; //幅(px)
lpdibh->biHeight = HEIGHT; //高さ(px)
lpdibh->biPlanes = 1; //必ず1
lpdibh->biBitCount = 24; //1ピクセル当たりのビット数
lpdibh->biCompression = BI_RGB; //非圧縮であることを示す
lpdibh->biSizeImage = IMG_SIZE; //ビットマップ(点の配列)の大きさ(バイト)
lpdibh->biClrUsed = 0; //カラー・マスクの数
lpdibh->biClrImportant = 0;
ここで,IMG_SIZE
(ビットマップのサイズ)を,HEIGHT
×WIDTH
×24とできないことに注意が必要.
32bit環境では,一行毎に4バイト(32ビット)の境界に揃える必要があるので,以下のような式でサイズを計算する.
HEIGHT * ( ( WIDTH * 3 + 3 ) & ~3 )
また,データを参照・変更する際には,DIBが(標準では)ボトム・アップで,BGRBGR・・・と並んでいることにも注意が必要.
最後にGetDIBits
関数を呼び出す前後の手順の一例を示す.
HDC hdc_src; //コピー元DCのハンドル
LPBITMAPINFOHEADER lpdibh; //必要な情報を格納したヘッダ
LPBYTE lpdata; //ビットマップ(点の配列)へのアドレス
/* 以上は取得・初期化済みであるとする(開放もしない) */
/// メモリ・デバイスコンテキストの作成
HDC hdcMem = ::CreateCompatibleDC( hdc_src );
/// ビットマップの作成
HBITMAP hbmp = ::CreateCompatibleBitmap( hdc_src , WIDTH , HEIGHT );
/// ビットマップとメモリ・デバイスコンテキストを関連付ける
HBITMAP hbmptmp = ::SelectObject( hdcMem , hbmp );
/// 画像をコピーする
::BitBlt( hdcMem , 0 , 0 , WIDTH , HEIGHT , hdc_src , X , Y , SRCCOPY );
/// DIBを取得する
::SelectObject( hdcMem , hbmptmp );
::GetDIBits( hdcMem , hbmp , 0 , HEIGHT , lpbmp , reinterpret_cast( lpdibh ) , DIB_RGB_COLORS );
/// リソースの開放
::DeleteObject( hbmp );
::DeleteDC( hdcMem );
参考:How To Convert Between Device-Dependent Bitmaps and DIBs,トップダウン DIB とボトムアップ DIB
0 件のコメント:
コメントを投稿