WICを使ってHBITMAPを取得

制作:KrK (Knuth for Kludge)

情報・ご感想はこちら

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


環境

ソース


#include <windows.h>    // Win32API
#include <wincodec.h>   // WIC
#include <objbase.h>    // COM
HBITMAP CreateHBitmapFromBitmapSource(IWICBitmapSource *pImage);

//-------------------------------------------------
// WICを使ってHBITMAPを取得
// 作成 20140913 KrK
// 引数 filename:ファイル名
// 戻り値:ビットマップハンドル
//-------------------------------------------------
HBITMAP LoadByWIC(WCHAR *filename)
{
    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イメージ

    // WIC初期化
    hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&pFactory));

    // デコーダを生成
    if (SUCCEEDED(hr))
    {
      hr = pFactory->CreateDecoderFromFilename(filename,
          NULL, GENERIC_READ, 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 (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;
}

使い方


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

// COM初期化
CoInitialize(NULL);

// ビットマップを読み込む
hBmp = LoadByWIC(filename);

(中略)

// 開放
CoUninitialize();
DeleteObject(hBmp);

使用条件

参考ページ


最終更新:2025/12/19

免責事項