HBITMAPをビットマップファイルに保存

制作:KrK (Knuth for Kludge)

情報・ご感想はこちら

KrK's Cracked Text > はしくれコード


環境

ソース


#include <windows.h>    // Win32API

//-------------------------------------------------
// HBITMAPをビットマップファイルに保存
// 作成 20160916 KrK
// 引数 hBmp:ビットマップハンドル
// 引数 filename:保存ファイル名
//-------------------------------------------------
VOID SaveImageFile(HBITMAP hBmp, WCHAR *filename)
{
    LONG imageSize;       // 画像サイズ
    BITMAPFILEHEADER fh;  // ビットマップファイルヘッダ
    BITMAPINFO *pbi;      // ビットマップ情報
    BITMAP bmp = { 0 };    // ビットマップ構造体
    LONG bpp;             // 画素数
    LPBYTE bits;          // 画像ビット
    HDC hdc;              // デバイスコンテキスト
    HDC hdc_mem;          // デバイスコンテキスト・メモリ
    HANDLE hFile;         // ファイラハンドル
    DWORD writeSize;      // 書き込んだサイズ

    // BITMAP情報を取得する
    GetObject(hBmp, sizeof(bmp), &bmp);
    hdc = GetDC(0);
    hdc_mem = CreateCompatibleDC(hdc);
    ReleaseDC(0, hdc);
    HBITMAP hBmpOld = (HBITMAP)SelectObject(hdc_mem, hBmp);

    // ファイルサイズ計算
    imageSize = bmp.bmWidthBytes * bmp.bmHeight
        + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    switch (bmp.bmBitsPixel)
    {
        case 2:
            bpp = 2;
            break;
        case 4:
            bpp = 16;
            break;
        case 8:
            bpp = 256;
            break;
        default:
            bpp = 0;
    }
    imageSize += (sizeof(RGBQUAD) * bpp);

    // BITMAPFILEHEADERヘッダー出力
    ZeroMemory(&fh, sizeof(fh));
    memcpy(&fh.bfType, "BM", 2);
    fh.bfSize = imageSize;
    fh.bfReserved1 = 0;
    fh.bfReserved2 = 0;
    fh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
        + sizeof(RGBQUAD) * bpp;

    // BITMAPINFOHEADERヘッダー出力
    pbi = new BITMAPINFO[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * bpp];
    ZeroMemory(pbi, sizeof(BITMAPINFOHEADER));
    pbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pbi->bmiHeader.biWidth = bmp.bmWidth;
    pbi->bmiHeader.biHeight = bmp.bmHeight;
    pbi->bmiHeader.biPlanes = 1;
    pbi->bmiHeader.biBitCount = bmp.bmBitsPixel;
    pbi->bmiHeader.biCompression = BI_RGB;
    if (bpp != 0)
    {
        GetDIBColorTable(hdc_mem, 0, bpp, pbi->bmiColors);
    }

    // 画像データを得る
    bits = new BYTE[bmp.bmWidthBytes * bmp.bmHeight];
    GetDIBits(hdc_mem, hBmp, 0, bmp.bmHeight, bits, pbi, DIB_RGB_COLORS);

    // ファイルに書き込む
    hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hFile, &fh, sizeof(fh), &writeSize, NULL);
    WriteFile(hFile, pbi,
        sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * bpp, &writeSize, NULL);
    WriteFile(hFile, bits, bmp.bmWidthBytes * bmp.bmHeight, &writeSize, NULL);
    CloseHandle(hFile);

    // 開放
    delete[] pbi;
    delete[] bits;
    SelectObject(hdc_mem, hBmpOld);
    DeleteDC(hdc_mem);
}

使い方


HBITMAP hBmp;               // ビットマップハンドル
WCHAR filename[_MAX_PATH];  // ファイル名

// ビットマップを読み込む
hBmp = ~;

// ビットマップをファイルに保存
SaveImageFile(hBmp, filename);

// 開放
DeleteObject(hBmp);

使用条件


最終更新:2023/09/13

免責事項