ビットマップをファイルに保存
ビットマップをファイルに保存するということは、ビットマップDIBを作成して、そのDIBを保存するということになります。
[備考]
色ビット数が16未満ならパレット情報(色調合情報であるRGBQUAD構造体)が存在し、それを読み込む必要があります。
しかし、最近の環境では32ビットのものが多いので、ここでは、RGBQUAD構造体の対応を省いています。
//クライアント領域の画像をDIBにして、ファイルへ保存
void CSaveBMPDlg::OnButton1()
{
RECT rc;
HDC hDC, hCompatibleDC;
HBITMAP hBitmap, hBitmapPrev;
BITMAPINFO *pbmi;
void *pbits;
HANDLE hfile;
DWORD tmp;
BITMAPFILEHEADER bmfh;
//ビットマップインフォを作成。
HWND hWnd = CSaveBMPDlg::m_hWnd;
//ビットマップをセーブする範囲(Client領域)を取得する
::GetClientRect(hWnd, &rc);
hDC = ::GetDC(hWnd);
pbmi = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)];
//BITMAPFILEHEADERの作成
ZeroMemory(&pbmi->bmiHeader, sizeof(pbmi->bmiHeader));
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = rc.right-rc.left;
pbmi->bmiHeader.biHeight = rc.bottom-rc.top;
pbmi->bmiHeader.biPlanes = 1;
//1ピクセルあたりビット数を格納
pbmi->bmiHeader.biBitCount = GetDeviceCaps(hDC, BITSPIXEL);
//ビットマップのバイト数を格納
//(今時の環境では、色は1ピクセル=4バイト表現なので、単純に*4とした。)
pbmi->bmiHeader.biSizeImage = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biHeight * 4;
//DIB を作成してウインドウからビットマップをコピー
hBitmap = CreateDIBSection(hDC, pbmi, DIB_RGB_COLORS, &pbits, NULL, 0);
hCompatibleDC = CreateCompatibleDC(hDC);
hBitmapPrev = (HBITMAP)SelectObject(hCompatibleDC, hBitmap);
BitBlt(hCompatibleDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, hDC, rc.left, rc.top, SRCCOPY);
SelectObject(hCompatibleDC, hBitmapPrev);
::ReleaseDC(hWnd, hDC);
//ビットマップファイルヘッダーを作成。
bmfh.bfType = 0x4D42; //BitMapファイルを表すコード
//("BM"をWORD型に格納したもので、決まりごとです。)
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfh.bfSize = bmfh.bfOffBits+pbmi->bmiHeader.biSizeImage;
//DIB をファイルへセーブ
hfile = CreateFile("TEST1.bmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
WriteFile(hfile, &bmfh, sizeof(bmfh), &tmp, NULL);
WriteFile(hfile, &pbmi->bmiHeader, sizeof(pbmi->bmiHeader), &tmp, NULL);
SetFilePointer(hfile, bmfh.bfOffBits, NULL, FILE_BEGIN);
WriteFile(hfile, pbits, pbmi->bmiHeader.biSizeImage, &tmp, NULL);
CloseHandle(hfile);
//BITMAPINFOの解放
delete[] (BYTE*)pbmi;
}