プロが教えるわが家の防犯対策術!

imgctl.dllの機能のひとつであるCreateDIB関数の使い方が分りません。

付属のリファレンスには
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
HDIB CreateDIB(const BITMAPINFO *pbmi, LPCVOID pvData)

BITMAPINFO構造体及び実データのビット並びからDIBデータを作成して、そのハンドルを返します。

v1.10B4 より、pvData にNULLを指定出来るようになりました。
NULLを指定した場合、実データ部が 0 で埋められたDIBデータを返します。
Visual Basic では、NULLの代わりに 0 を指定します。

v1.12B3 より、トップダウン形式からの作成が可能になりました。

====================
ICERR_MEM_ALLOC
ICERR_PARAM_NULL
ICERR_IMG_COMPRESS
ICERR_IMG_RLESIZE
ICERR_IMG_BITCOUNT
ICERR_IMG_AREA
ICERR_IMG_RLETOP
====================
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

とありますが、引数LPCVOID pvDataには何を渡せば良いのでしょうか、
BITMAP構造体だと思ったのですがうまくいきません。
どうかよろしくお願いします。

A 回答 (2件)

 こんばんは。


 すんません、的ハズレな事を書いてしまいました。NULLの場合ではなく、pvDataに何を入れるべきかと言う事でした。
 pvDataには、これから作成するDIBの元となる、グラフィックの配列を入れると言う事です。
 例えば、これから作成するDIBが 320 x 240 x 24bit(3byte)である場合、 320 x 240 x 3 = 230400byte の一次元配列を入れる事になります(その位置次元配列に絵のデータが入っている訳です)。

//320 x 240 x 24bitの真っ黒なDIBハンドルを作成する
BITMAPINFO bmi = {sizeof(BITMAPINFOHEADER)};
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biWidth = 320;
bmi.bmiHeader.biHeight = 240;

//1ピクセル辺りのバイト数
const int bytesPerPixel = (bmi.bmiHeader.biBitCount / 8);

//1行辺りのバイト数
const int strideByte = bmi.bmiHeader.biWidth * bytesPerPixel;

//イメージ全体のバイト数
bmi.bmiHeader.biSizeImage = bmi.bmiHeader.biWidth * bmi.bmiHeader.biHeight * bytesPerPixel;

//グローバルメモリを作成する(win32api)
HGLOBAL hMem = ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, bmi.bmiHeader.biSizeImage);

//グローバルメモリからポインタを開く(win32api)
LPBYTE pData = (LPBYTE)::GlobalLock(hMem);

//適当にグラデーションを作る
for(int y = 0; y < bmi.bmiHeader.biHeight; ++y)
for(int x = 0; x < bmi.bmiHeader.biWidth; ++x)
{
const int pos= (x * bytesPerPixel) + (y * strideByte);
pData[pos]= x * ((double)255 / (double)bmi.bmiHeader.biWidth);
pData[pos+1]= 0xff;
pData[pos+2]= (bmi.bmiHeader.biWidth - x) * ((double)255 / (double)bmi.bmiHeader.biWidth);
}

//先程作成したpDataを元にDIBハンドルを作成する(imgctl.dll)
HDIB hDIB = ::CreateDIB(&bmi, pData);

//ウィンドウデバイスコンテキストを取る(win32api)
HDC hDC = ::GetDC(hWnd);

//ウィンドウに描写する(imgctl.dll)
::DIBtoDC(hDC, 0, 0, bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight, hDIB, 0, 0, SRCCOPY);

//ウィンドウデバイスコンテキストの解放(win32api)
::ReleaseDC(hWnd, hDC);

//DIBハンドルを消去(imgctl.dll)
::DeleteDIB(hDIB);

//グローバルメモリのポインタを閉じる(win32api)
::GlobalUnlock(hMem);

//グローバルメモリを消去(win32api)
::GlobalFree(hMem);
    • good
    • 0
この回答へのお礼

お礼が遅れてすみません。

すばらしい!貴重なコードをありがとうございます。
問題解決しました。また何かありましたらよろしくお願いします。

お礼日時:2009/06/04 14:37

 こんばんは。


 NULLを入れると、真っ黒なDIBを作成するのだそうです。
 HDIB型はHBITMAP型とは関係ないので、SelectObject()api等に渡してはいけないので要注意。
 以下はウィンドウに真っ黒なDIBを表示します。参考程度に。

//320 x 240 x 24bitの真っ黒なDIBハンドルを作成する
BITMAPINFO bmi = {sizeof(BITMAPINFOHEADER)};
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biWidth = 320;
bmi.bmiHeader.biHeight = 240;

//DIBハンドルを作成する(imgctl.dll)
HDIB hDIB = ::CreateDIB(&bmi, NULL);

//ウィンドウデバイスコンテキストを取る(win32api)
HDC hDC = ::GetDC(hWnd);

//ウィンドウに描写する(imgctl.dll)
::DIBtoDC(hDC, 0, 0, bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight, hDIB, 0, 0, SRCCOPY);

//ウィンドウデバイスコンテキストの解放(win32api)
::ReleaseDC(hWnd, hDC);

//DIBハンドルを消去(imgctl.dll)
::DeleteDIB(hDIB);
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!