DDBのままBMPファイルに保存する事はできないので、DIBに変換する必要があります。
その為の関数もありますが、今までに勉強してきた技術の組み合わせで
この問題を解決する事ができます。
新しい関数を暗記するより、既存技術の工夫が大切ですよね。
■DDBをDIBに変換する
答えから言うと「同じサイズのDIBSectionを作って、DDBをコピーする」事で、
DIBSectionから元のDDBと同じDIBが得られます。
コピーする時はDDBとしてコピーするので、
ビット数は自動的にコピー先のDIBSectionと同じになります。
DDBのビット数は不明ですが、24ビットDIBSectionなら全てに対応できるでしょう。
DIBSectionにコピーしたら、後はDIBとして保存すればいいだけです。
DIBSectionをBMPファイルに保存する処理はSaveDIB関数にまとめてあります。
詳しくは前節、前々節をご覧下さい。
今回作成するのはSaveDIB関数を呼び出す関数です。
SaveDIB 関数は外部に公開しません。
関数名 → SaveDDB
引数 → ファイル名 , DDBのデバイスコンテキストハンドル , 横幅 , 高さ
戻り値 → SaveDIB関数の戻り値 : 0 (成功) or 負値(失敗)
int SaveDDB(char *lpFileName,HDC hMemDC,int width,int height)
{
BITMAPINFO bmpInfo;
LPBYTE lpPixel;
//DIBの情報を設定する
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth=width;
bmpInfo.bmiHeader.biHeight=height;
bmpInfo.bmiHeader.biPlanes=1;
bmpInfo.bmiHeader.biBitCount=24;
bmpInfo.bmiHeader.biCompression=BI_RGB;
//DIBSection作成
HBITMAP hBmp=CreateDIBSection(NULL,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0);
HDC hdcTemp=CreateCompatibleDC(NULL);
SelectObject(hdcTemp,hBmp);
BitBlt(hdcTemp,0,0,width,height,hMemDC,0,0,SRCCOPY);
int ret=SaveDIB(lpFileName,lpPixel,&bmpInfo);
DeleteDC(hdcTemp);
DeleteObject(hBmp);
return ret;
}
24ビットDIBSectionを作成して、DDBをコピー、
SaveDIB関数を呼び出してDIBとしてBMPファイルに保存、
最後にDIBSectionを削除して関数終了です。
アイディアの勝利って感じですね!
■SaveDDB関数の呼び出し
DDBを作成して、24ビットBMPファイルとして保存してみます。
#include<windows.h>
#include"SaveBMP.h"
#define WIDTH 197
#define HEIGHT 100
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBITMAP hBitmap;
static HDC hMemDC;
switch(uMsg) {
case WM_CREATE:
//メモリデバイスコンテキストを作る
hdc=GetDC(hWnd);
hMemDC=CreateCompatibleDC(hdc);
hBitmap=CreateCompatibleBitmap(hdc,WIDTH,HEIGHT);
ReleaseDC(hWnd,hdc);
SelectObject(hMemDC,hBitmap);
DeleteObject(hBitmap);
//描画
SelectObject(hMemDC,GetStockObject(GRAY_BRUSH));
Rectangle(hMemDC,25,25,50,50);
//BMPファイルに保存
SaveDDB("ddb_bmp24.bmp",hMemDC,WIDTH,HEIGHT);
return 0;
case WM_DESTROY:
DeleteDC(hMemDC);
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
//表画面へ転送
BitBlt(hdc,0,0,WIDTH,HEIGHT,hMemDC,0,0,SRCCOPY);
EndPaint(hWnd,&ps);
return 0;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

★☆ ダウンロード ☆★
■SaveBMP.h
SaveBMP.h はDIB、DIBSection、DDBをファイルに保存する関数を集めたヘッダーです。
DIB の保存にはSaveDIB関数を使います。
DDB の保存には SaveDDB関数を使います。
DIBSection の保存にはどちらも使えますが、
SaveDDB関数は内部でSaveDIB関数を呼び出しているので、SaveDIB関数を使うべきです。
// SaveBMP.cpp int SaveDIB(char *lpFileName,const BYTE *lpPixel,const BITMAPINFO *lpBmpInfo); int SaveDDB(char *lpFileName,HDC hMemDC,int width,int height);