既存のIWICBitmapSourceからの構築
すでにWICでメモリ上に持っているIWICBitmapSourceをコピーしてビットマップを初期化したい場合には、次のようなコードを書く必要があるかもしれません。エラーの処理は適当に追加してください。
// 適当に例外を投げるためのマクロ; 手抜きなので注意!!! #define throwOnFail(expr) do { HRESULT hr = expr; if(FAILED(hr)) throw hr; } while(0) // 入力ソースをBGR(プロファイルがある場合には、sRGB)に変換 IWICBitmapSource* ConvertToSRGB(IWICBitmapSource* bmpSrc, IWICImagingFactory* factory) { WICPixelFormatGUID fmt; throwOnFail(bmpSrc->GetPixelFormat(&fmt)); // RGBの画像じゃない場合には、カラープロファイルを用いたIWICColorTransformによる変換を試みる if(fmt != GUID_WICPixelFormat24bppBGR && fmt !=GUID_WICPixelFormat24bppRGB) { UINT co; CComPtr<IWICColorContext> cc_src; HRESULT hr = bmpSrc->GetColorContexts(1, &cc_src, &co); if(SUCCEEDED(hr) && co == 1 && cc_src) { // sRGB profile CComPtr<IWICColorContext> cc_sRGB; throwOnFail(factory->CreateColorContext(&cc_sRGB)); throwOnFail(cc_sRGB->InitializeFromExifColorSpace(1)); CComPtr<IWICColorTransform> txf; throwOnFail(factory->CreateColorTransformer(&txf)); throwOnFail(txf->Initialize( frameDecode, cc_src, cc_sRGB, GUID_WICPixelFormat24bppBGR)); IWICBitmapSource* output = NULL; throwOnFail(txf->QueryInterface( __uuidof(IWICBitmapSource), (void**)&output)); return output; } } // どうにもうまくいかない場合には、適当に変換する CComPtr<IWICFormatConverter> cvtr; throwOnFail(factory->CreateFormatConverter(&cvtr)); throwOnFail(cvtr->Initialize( bmpSrc, GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom)); IWICBitmapSource* output = NULL; throwOnFail(cvtr->QueryInterface( __uuidof(IWICBitmapSource), (void**)&output)); return output; } // CComPtr<CWICGdiplusBgrBitmap> CopyToGdiplusBitmap(IWICBitmapSource* src, IWICImagingFactory* factory) { CComPtr<IWICBitmapSource> bmpSrc = ConvertToSRGB(src, factory); UINT w, h; throwOnFail(bmpSrc->GetSize(&w, &h)); CComPtr<CWICGdiplusBgrBitmap> outBmp; outBmp = CWICGdiplusBgrBitmap::Create(w, h); double resX, resY; if(SUCCEEDED(bmpSrc->GetResolution(&resX, &resY))) outBmp->SetResolution(resX, resY); CComPtr<IWICBitmapLock> lock; WICRect rcCopy = {0, 0, w, h}; throwOnFail(outBmp->Lock(&rcCopy, WICBitmapLockWrite, &lock)); UINT stride = 0, bufSize = 0; BYTE* raw = NULL; throwOnFail(lock->GetDataPointer(&bufSize, &raw)); throwOnFail(lock->GetStride(&stride)); throwOnFail(bmpSrc->CopyPixels(&rcCopy, stride, bufSize, raw)); return outBmp; }