ウィンドウのビットマップ保存 – プログラミング – Home

ウィンドウのビットマップ保存
 
通知
すべてクリア

ウィンドウのビットマップ保存


kool-fox
 kool-fox
(@kool-fox)
ゲスト
結合: 17年前
投稿: 6
Topic starter  

お世話になります。

VC6 MFC ダイアログベース

でプログラムを作成しています。

今回教えていただきたいのは、ボタンを押すと画面をキャプチャーしてビットマップで保
存する方法です。
いろいろなサイトでビットマップ保存する仕方が書いてありますが、どこにソースを書き
込めばいいかわかりません。

以下ソースです。
///////////////////////////////////////////////////////
void CPict_line_2Dlg::OnButton4()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
CDC *pDC; // デバイスコンテキスト
CDC DCMem; // メモリデバイスコンテキスト
HBITMAP hBitmap;// ビットマップハンドル
HBITMAP Soh; // ビットマップハンドル
CRect rect; // ダイアログ領域

// ハードコピーするウィンドウを決定する
CWnd *pWnd = AfxGetApp()->m_pMainWnd;

// 指令されたウィンドウの領域を取得する
pWnd->GetWindowRect(&rect);

// ディスプレイ デバイスコンテキスト作成
pDC = pWnd->GetWindowDC(); // 注)GetDC()は、クライアント領域になる
LPBITMAPINFO lpbi;
LPTSTR lpBits = NULL;

#define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)

// Fill in the BITMAPINFOHEADER
lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = rect.Width();
lpbi->bmiHeader.biHeight = rect.Height();
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 24;
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = WIDTHBYTES(rect.Width()) * rect.Height();
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;

hBitmap = CreateDIBSection(pDC->m_hDC, lpbi, DIB_RGB_COLORS, (void **)&lpBits,
NULL, 0);

// DSPメモリ デバイスコンテキスト作成
DCMem.CreateCompatibleDC(pDC);
Soh = (HBITMAP)SelectObject(DCMem.m_hDC, hBitmap);

// ビットマップ複写
DCMem.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);

}
///////////////////////////////////////////////////////

よろしくお願いします。


引用解決済
トピックタグ
まえだ
 まえだ
(@まえだ)
ゲスト
結合: 17年前
投稿: 10
 

OnButton4()
が分からないってこと?


返信引用
ドルドル
 ドルドル
(@ドルドル)
ゲスト
結合: 19年前
投稿: 96
 

 kool-fox さん。
 2点ほど述べさせていただきます。
 
1 GetDIBits()を調べてみてください。あとMFCを使われているので CBitmapクラスな
どで検索すればサンプルとか見つかると思います。

2 ソースみて思ったのですが、ビットマップのファイルフォーマットはご存じです
か?? 例えば下記のdefine定義が意味していること、BITMAPINFOHEADERが表すことなど
です
> #define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)

 もし、そのあたりがご存じないようでしたら、一度ビットマップのファイルフォーマッ
トの調べられることをお勧めします。 保存処理に必要な知識になってきますので。。。
”ビットマップ フォーマット”などで検索すればすぐにでてくると思います。

がんばってください。


返信引用
kool-fox
 kool-fox
(@kool-fox)
ゲスト
結合: 17年前
投稿: 6
Topic starter  

まえだ様、ドルドル様、お返事ありがとうございます。

今回載せたソースは、ネットで調べてコピペしただけのものなので、
プログラムのことは何も分かっておりません、申し訳ありません。

GetDIBits()
CBitmapクラス
ビットマップ フォーマット

この点について調べてみたいと思います。
また分からないことがあったらお聞きしますので、
よろしくお願います。ありがとうございました。


返信引用
kool-fox
 kool-fox
(@kool-fox)
ゲスト
結合: 17年前
投稿: 6
Topic starter  

お世話になります。

調べたところ、このようなソースコードを拾ってきました。

void saveBMP(HWND hwnd,LPCTSTR lpszFn) {

DWORD dwSize,dwFSize,dwWidth,dwHeight,dwLength;
HANDLE fh;
LPBITMAPFILEHEADER lpHead;
LPBITMAPINFOHEADER lpInfo;
LPBYTE lpBuf,lpPixel;
RECT rec;
HDC hdc,hdcMem;
HBITMAP hBMP,hOld;

GetClientRect(hwnd,&rec); /* クライアント領域取得 */

dwWidth=rec.right;
dwHeight=rec.bottom;

if ((dwWidth*3) % 4==0) /* バッファの1ラインの長さを計算 */
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);

/* 24ビット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=GetDC(hwnd);
/* ウインドウのデバイスコンテキスト互換のBITMAP作成 */
hBMP=CreateCompatibleBitmap(hdc,dwWidth,dwHeight);

/* BITMAPにウインドウのクライアント領域をコピー */
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);

ReleaseDC(hwnd,hdc);
DeleteObject(hBMP);
DeleteObject(hdcMem);

/* バッファをファイルに書き出す */
fh=CreateFile(lpszFn,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(fh,lpBuf,dwFSize,&dwSize,NULL);
CloseHandle(fh);

GlobalFree(lpBuf);

}

このあとに、

void CPict_line_2Dlg::OnButton4()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
saveBMP([描画しているウインドウ].GetSafeHWnd(),test.bmp);
}

とすれば、保存できそうなのですが、[描画しているウィンドウ]には何を書き込めばいい
かわかりません。
どうかご教授お願いします。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました