制作:KrK (Knuth for Kludge)
#include <wincodec.h> // WIC
#include <objbase.h> // COM
#define kMODE_PNG 0
#define kMODE_BMP 1
#define kMODE_JPG 2
//---------------------------------------------------------------------
// HBITMAPをWICを使ってファイルに保存
// 作成 20251219 KrK
// 引数 hBmp:ビットマップハンドル
// 引数 filename:保存ファイル名
// 引数 mode:モード
// 引数 quality:JPEG品質
//---------------------------------------------------------------------
VOID SaveWicFile(HBITMAP hBmp, WCHAR* filename, LONG mode, ULONG quality)
{
IWICImagingFactory *pFactory = NULL;
IWICBitmap *pWICBitmap = NULL;
IWICStream *pStream = NULL;
IWICBitmapEncoder *pEncoder = NULL;
IWICBitmapFrameEncode *pFrameEncode = NULL;
IPropertyBag2* pPropertybag = NULL;
// 初期化
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pFactory));
// HBITMAPからWICビットマップを生成
if (SUCCEEDED(hr))
{
hr = pFactory->CreateBitmapFromHBITMAP(
hBmp,
NULL,
WICBitmapUseAlpha,
&pWICBitmap);
}
// WICストリームを生成
if (SUCCEEDED(hr))
{
hr = pFactory->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
hr = pStream->InitializeFromFilename(filename, GENERIC_WRITE);
}
// エンコーダ生成
if (SUCCEEDED(hr))
{
// Use the GUID for container format
if (mode == kMODE_BMP)
{
hr = pFactory->CreateEncoder(GUID_ContainerFormatBmp,
NULL, &pEncoder);
}
else if (mode == kMODE_PNG)
{
hr = pFactory->CreateEncoder(GUID_ContainerFormatPng,
NULL, &pEncoder);
}
else
{
hr = pFactory->CreateEncoder(GUID_ContainerFormatJpeg,
NULL, &pEncoder);
}
}
// ストリームでエンコーダを初期化
if (SUCCEEDED(hr))
{
hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache);
}
// フレームを生成
if (SUCCEEDED(hr))
{
hr = pEncoder->CreateNewFrame(&pFrameEncode, &pPropertybag);
}
// JPEGオプション
if (mode == kMODE_JPG)
{
if (SUCCEEDED(hr))
{
PROPBAG2 option = { 0 };
option.vt = VT_R4;
WCHAR wstr[64];
wcscpy_s(wstr, L"ImageQuality");
option.pstrName = (LPOLESTR)wstr;
VARIANT varValue;
VariantInit(&varValue);
varValue.vt = VT_R4;
varValue.fltVal = (FLOAT)quality / 100;
hr = pPropertybag->Write(1, &option, &varValue);
}
}
// フレームを初期化
if (SUCCEEDED(hr))
{
hr = pFrameEncode->Initialize(pPropertybag);
}
// ビットマップデータをフレームに書き込む
if (SUCCEEDED(hr))
{
hr = pFrameEncode->WriteSource(
static_cast<IWICBitmapSource*>(pWICBitmap), NULL);
}
// ファイルに書き込む
if (SUCCEEDED(hr))
{
hr = pFrameEncode->Commit();
}
if (SUCCEEDED(hr))
{
hr = pEncoder->Commit();
}
// 解放
if (pPropertybag != NULL)
{
pPropertybag->Release();
}
if (pFrameEncode != NULL)
{
pFrameEncode->Release();
}
if (pEncoder != NULL)
{
pEncoder->Release();
}
if (pStream != NULL)
{
pStream->Release();
}
if (pWICBitmap != NULL)
{
pWICBitmap->Release();
}
if (pFactory != NULL)
{
pFactory->Release();
}
}
HBITMAP hBmp; // ビットマップハンドル
WCHAR filename[_MAX_PATH]; // ファイル名
// COM初期化
CoInitialize(NULL);
// ビットマップを読み込む
hBmp = ~;
// ビットマップをファイルに保存
SaveWicFile(hBmp, filename, kMODE_PNG, 100);
// 解放
CoUninitialize();
DeleteObject(hBmp);
最終更新:2025/12/19