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);