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);

使用条件


最終更新:2023/09/14

免責事項