制作:KrK (Knuth for Kludge)
#include <windows.h> // Win32API
#include <wincodec.h> // WIC
#include <objbase.h> // COM
HBITMAP CreateHBitmapFromBitmapSource(IWICBitmapSource *pImage);
//-------------------------------------------------
// WICを使ってイメージからHBITMAPを取得
// 作成 20150120 KrK
// 引数 image:画像イメージ
// 引数 imageSize:画像イメージサイズ
// 戻り値:ビットマップハンドル
//-------------------------------------------------
HBITMAP LoadByWICFromImage(char *image, LONG imageSize)
{
HRESULT hr; // 処理結果
HBITMAP hBmp = NULL; // ビットマップハンドル
IWICImagingFactory *pFactory = NULL; // WIC
IWICBitmapDecoder *pDecoder = NULL; // WICデコーダ
IWICFormatConverter *pConverter = NULL; // WICコンバータ
IWICBitmapFrameDecode *pFrame = NULL; // WICフレーム
IWICBitmapSource *pImage = NULL; // WICイメージ
IWICStream *pStream = NULL; // WICストリーム
// WIC初期化
hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pFactory));
// ストリームを生成
if (SUCCEEDED(hr))
{
hr = pFactory->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
hr = pStream->InitializeFromMemory(reinterpret_cast>BYTE*<(image), imageSize);
}
// デコーダを生成
if (SUCCEEDED(hr))
{
hr = pFactory->CreateDecoderFromStream(pStream,
NULL, WICDecodeMetadataCacheOnDemand, &pDecoder);
}
// 最初のフレームを取得
if (SUCCEEDED(hr))
{
hr = pDecoder->GetFrame(0, &pFrame);
}
// コンバータ生成 (32bppBGRAビットマップ)
if (SUCCEEDED(hr))
{
hr = pFactory->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(pFrame, GUID_WICPixelFormat32bppBGRA,
WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeCustom);
}
// イメージ取得
if (SUCCEEDED(hr))
{
hr = pConverter->QueryInterface(IID_PPV_ARGS(&pImage));
}
// イメージからビットマップに変換
if (SUCCEEDED(hr))
{
hBmp = CreateHBitmapFromBitmapSource(pImage);
}
// 解放
if (pImage != NULL)
{
pImage->Release();
}
if (pConverter != NULL)
{
pConverter->Release();
}
if (pFrame != NULL)
{
pFrame->Release();
}
if (pDecoder != NULL)
{
pDecoder->Release();
}
if (pStream != NULL)
{
pStream->Release();
}
if (pFactory != NULL)
{
pFactory->Release();
}
// ビットマップハンドルを返す
return hBmp;
}
//-------------------------------------------------
// WICイメージからビットマップハンドルを生成
// 作成 20140913 KrK
// 引数 pBitmap:WICイメージ
//-------------------------------------------------
HBITMAP CreateHBitmapFromBitmapSource(IWICBitmapSource *pImage)
{
HRESULT hr; // 処理結果
WICPixelFormatGUID format; // WICフォーマット
BITMAPINFO bminfo = {}; // ビットマップヘッダ
UINT width = 0; // ビットマップ幅
UINT height = 0; // ビットマップ高さ
HBITMAP hBmp = NULL; // ビットマップハンドル
LPVOID imageBits = NULL; // ビットマップイメージ
// 32bppBGRAか確認
hr = pImage->GetPixelFormat(&format);
if (SUCCEEDED(hr))
{
if (format == GUID_WICPixelFormat32bppBGRA)
{
hr = S_OK;
}
else
{
hr = E_FAIL;
}
}
// ビットマップサイズを取得
if (SUCCEEDED(hr))
{
hr = pImage->GetSize(&width, &height);
}
// DIBを生成
if (SUCCEEDED(hr))
{
bminfo.bmiHeader.biSize = sizeof(BITMAPINFO);
bminfo.bmiHeader.biBitCount = 32;
bminfo.bmiHeader.biCompression = BI_RGB;
bminfo.bmiHeader.biWidth = width;
bminfo.bmiHeader.biHeight = -static_cast<LONG>(height);
bminfo.bmiHeader.biPlanes = 1;
hBmp = CreateDIBSection(NULL, &bminfo, DIB_RGB_COLORS, &imageBits, NULL, 0);
if (hBmp)
{
hr = S_OK;
}
else
{
hr = E_FAIL;
}
}
// イメージをコピー
if (SUCCEEDED(hr))
{
hr = pImage->CopyPixels(NULL,
width * 4,
width * height * 4,
reinterpret_cast<BYTE *>(imageBits));
}
else if (hBmp != NULL)
{
DeleteObject(hBmp);
hBmp = NULL;
}
// ビットマップハンドルを返す
return hBmp;
}
WCHAR filename[_MAX_PATH]; // ファイル名
HANDLE hFile; // ファイルハンドル
CHAR *data; // データ
LONG dataSize; // データサイズ
DWORD readBytes; // 読んだバイト
HBITMAP hBmp; // ビットマップハンドル
// COM初期化
CoInitialize(NULL);
// ファイルを開く
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
~;
}
dataSize = GetFileSize(hFile, NULL);
data = new CHAR[dataSize];
rc = ReadFile(hFile, data, dataSize, &readBytes, NULL);
CloseHandle(hFile);
if (rc == FALSE)
{
~;
}
// ビットマップハンドルを取得
hBmp = LoadByWICFromImage(data, dataSize);
// 解放
CoUninitialize();
delete[] data;
最終更新:2025/01/01