デバイスコンテキストを取得し、ビットマップをしてつかうには?


ゆい  2007-02-04 19:59:48  No: 64378

現在、スクリーンキャプチャした画像をビットマップとして利用たいと思い、下記のようなソースプログラムを作ったのですが、イメージとしてビットマップを読み出す事ができません。
        DWORD dwSize,dwFSize,dwWidth,dwHeight,dwLength;
TCHAR strFile[MAX_PATH]="";
HANDLE hFile;
LPBITMAPFILEHEADER lpHead;
LPBYTE lpBuf,lpPixel;
HDC hdc,hdcMem;
HBITMAP hBMP,hOld;
OPENFILENAME ofn={0};

dwWidth=1280;
dwHeight=1024;
// バッファの1ラインの長さを計算
if((dwWidth*3)%4==0)dwLength=dwWidth*3;
else dwLength=dwWidth*3+(4-(dwWidth*3)%4);
// 書き込み用バッファのサイズ計算
dwFSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwLength*dwHeight;
// バッファ確保とポインタ設定
lpBuf=(LPBYTE)GlobalAlloc(GPTR,dwFSize);
lpHead=(LPBITMAPFILEHEADER)lpBuf;
lpInfo=(LPBITMAPINFOHEADER)(lpBuf+sizeof(BITMAPFILEHEADER));
lpPixel=lpBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
//BMPファイルのヘッダの作成
lpHead->bfType='M'*256+'B';
lpHead->bfSize=dwFSize;
lpHead->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
lpInfo->biSize=sizeof(BITMAPINFOHEADER);
lpInfo->biWidth=dwWidth;
lpInfo->biHeight=dwHeight;
lpInfo->biPlanes=1;
lpInfo->biBitCount=24;
// ウインドウのデバイスコンテキスト取得
hdc = CreateDC(TEXT("DISPLAY") , NULL , NULL , NULL);
//ウインドウのデバイスコンテキストと互換のBITMAPを作成 
hBMP=CreateCompatibleBitmap(hdc,dwWidth,dwHeight);
//クライアント領域を取得
hdcMem=CreateCompatibleDC(hdc);
hOld=(HBITMAP)SelectObject(hdcMem,hBMP);
BitBlt(hdcMem,0,0,dwWidth,dwHeight,hdc,0,0,SRCCOPY);
SelectObject(hdcMem,hOld);
GetDIBits(hdc,hBMP,0,dwHeight,lpPixel,(LPBITMAPINFO)lpInfo,DIB_RGB_COLORS);
//後処理
DeleteDC(hdc);
DeleteObject(hBMP);
DeleteObject(hdcMem);

この処理をさせた後、デバイスコンテキストから取得したビットマップをファイルから読み出しの変わりに利用するにはどうしたらいいのでしょうか?


ゆい  2007-02-04 20:03:26  No: 64379

多重投稿してしまいました。
もうしわけありません。


( 'o')  URL  2007-02-04 22:01:52  No: 64380

> この処理をさせた後

この処理が何なのか理解するまでがしんどい。

> デバイスコンテキストから取得したビットマップをファイルから読み出しの変わりに利用する

俺にはよくわからなかった。


( 'o')  2007-02-04 22:24:07  No: 64381

もしかしてSetDIBitsToDeviceの逆のやつがほしいってことか。
そういえば無いねえ。

それとも失敗しているってこと?
それなら戻り値を見るべきでしょ。
というか戻り値を見ないプログラムが多すぎ。
そういう俺も結構見てないけどさ。


オショウ  2007-02-05 00:28:53  No: 64382

これじゃ〜取れないというか無茶苦茶・・・

どうもデスクトップウィンドウ全てを画像として保存したいようですので

// ウインドウのデバイスコンテキスト取得
hdc = CreateDC(TEXT("DISPLAY") , NULL , NULL , NULL);

※  この記述、IBM OS/2 みたいな書き方?

デスクトップのデバイスコンテキストを取るなら・・・
オーソドックスに!

hdc = GetDC( GetDesktopWindow() );

※  マルチディスプレイの場合は・・・
    hdc = GetDC( NULL );
    で仮想画面全てが取得できるようになります。

で・・・

/* ウインドウのデバイスコンテキスト互換のBITMAP作成 */
hBMP=CreateCompatibleBitmap(hdc,dwWidth,dwHight);
/* BITMAPにウインドウのクライアント領域をコピー */
hdcMem=CreateCompatibleDC(hdc);
hOld=(HBITMAP)SelectObject(hdcMem,hBMP);
BitBlt(hdcMem,0,0,dwWidth,dwHight,hdc,VirtualRec.left,VirtualRec.top,SRCCOPY);
SelectObject(hdcMem,hOld);
GetDIBits(hdcMem,hBMP,0,dwHight,lpPixel,(LPBITMAPINFO)lpInfo,DIB_RGB_COLORS);
ReleaseDC(hwnd,hdc);
DeleteObject(hBMP);
DeleteObject(hdcMem);

後は最後にファイルに書き出す・・・と言う手順。

※  私の自作のソースコードから抜きましたので、変数名は推測して
    下さい。

参考までに

以上。


PATIO  2007-02-06 00:09:46  No: 64383

単純にファイルから読み込んだビットマップの代わりに使いたいだけなら
オショウさんが書いている中のhBMPを使って処理すればいいだけです。
なのでDeleteObjectはこのタイミングでするのではなくてそのビットマップが
不要になるタイミングと言う事になります。
ずっと使いまわすなら、アプリが起動する時に画面にコンパチブルなビット
マップを作成しておいて、必要なタイミングでデスクトップからBitBltして
以降は使いまわしかな。
BitBltする時にコンパチブルなDCに一度Selectする必要がありますけれど、
単にビットマップとしてだけ使いたいならBitBlt後、Selectは解除しておく
必要があると思います。
最終的にそのビットマップが不要になるタイミング(例えばアプリの終了)で
ビットマップをDeleteObjectすれば良いのではないでしょうか。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加