DDBをBMPファイルに保存する

概要:DDBをBMPファイルに保存する関数を作成します

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

戻る / ホーム