HBITMAPをGDI+を使ってファイルに保存

制作:KrK (Knuth for Kludge)

情報・ご感想はこちら

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


環境

ソース


// GDI+
#include <gdiplus.h>
#include <gdiplusheaders.h>
#pragma comment(lib, "Gdiplus.lib")
using namespace Gdiplus;

#define kMODE_PNG    0
#define kMODE_BMP    1
#define kMODE_JPG    2

//---------------------------------------------------------------------
// HBITMAPをGDI+を使ってファイルに保存
// 作成 20251219 KrK
// 引数 hBmp:ビットマップハンドル
// 引数 filename:保存ファイル名
//---------------------------------------------------------------------
VOID GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT num = 0;     // エンコーダ数
    UINT size = 0;    // エンコーダサイズ

    ImageCodecInfo* pImageCodecInfo = NULL;

    // エンコーダサイズ数、サイズ取得
    GetImageEncodersSize(&num, &size);
    if (size == 0)
    {
        return;
    }

    // コーデック情報初期化
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
    {
        return;
    }

    // エンコーダ取得
    GetImageEncoders(num, size, pImageCodecInfo);

    // エンコーダの数だけ処理
    for (UINT i = 0; i < num; i++)
    {
        // フォーマットが一致
        if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[i].Clsid;
            free(pImageCodecInfo);
            return;
        }
    }

    free(pImageCodecInfo);
    return;
}
VOID SaveGdipluFile(HBITMAP hBmp, WCHAR* filename, LONG mode, ULONG quality)
{
    CLSID encoderClsid = GUID_NULL;
    Bitmap* image = Bitmap::FromHBITMAP(hBmp, NULL);

    // PNG
    if (mode == kMODE_PNG)
    {
        //Getting data from the bitmap and creating new bitmap from it
        Rect rect(0, 0, image->GetWidth(), image->GetHeight());
        BitmapData bd;
        image->LockBits(&rect, ImageLockModeRead,
            image->GetPixelFormat(), &bd);
        Bitmap* newBitmapWithAplha =
            new Bitmap(bd.Width, bd.Height, bd.Stride,
            PixelFormat32bppARGB, (BYTE*)bd.Scan0);
        image->UnlockBits(&bd);

        GetEncoderClsid(L"image/png", &encoderClsid);
        newBitmapWithAplha->Save(filename, &encoderClsid, NULL);

        delete newBitmapWithAplha;
    }
    else if (mode == kMODE_BMP)
    {
        GetEncoderClsid(L"image/bmp", &encoderClsid);
        image->Save(filename, &encoderClsid, NULL);
    }
    else
    {
        GetEncoderClsid(L"image/jpeg", &encoderClsid);

        EncoderParameters encoderParameters;
        encoderParameters.Count = 1;
        encoderParameters.Parameter[0].Guid = EncoderQuality;
        encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
        encoderParameters.Parameter[0].NumberOfValues = 1;
        encoderParameters.Parameter[0].Value = &quality;
        image->Save(filename, &encoderClsid, &encoderParameters);
    }

    delete image;
}

使い方


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

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

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

// 開放
DeleteObject(hBmp);

使用条件

参考ページ


最終更新:2025/12/19

免責事項