デバイス・コンテキストから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 件のコメント:
コメントを投稿