2016-10-03 13 views
1

WICを使用してファイルから画像を読み込み、Direct2Dで画面に表示しようとしています。 MSDN exampleに従っていますが、CreateBitmapFromWicBitmap()関数に問題が発生しました。私はID2D1HwndRenderTarget作成とIWICFormatConverter::Initialize()関数呼び出し中に使用pixel formatsの組み合わせID2D1HwndRenderTarget :: CreateBitmapFromWicBitmap()

に関係なく、CreateBitmapFromWicBitmap()戻り0x88982f80エラー(WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT)として機能します。

私は描画に使用するのと同じID2D1HwndRenderTargetを使用して関数を呼び出します。別のレンダーターゲットを作成する必要がありますか?

このlinkのコメントセクションで、DXGIサーフェスレンダーターゲットによってCreateBitmapFromWicBitmap()が呼び出されるべきだと誰かが書きました。この機能は単にID2D1HwndRenderTargetと一緒に使用できないという意味ですか?

EDIT:

void LoadBitmapFromFile(ID2D1HwndRenderTarget* target, ID2D1Bitmap** ppBitmap) 
{ 
    IWICImagingFactory* factory; 
    IWICBitmapDecoder* decoder; 
    IWICBitmapFrameDecode* frame; 
    IWICFormatConverter* converter; 

    CoInitializeEx(0, COINIT_MULTITHREADED); 
    CoCreateInstance(CLSID_WICImagingFactory1, 
        NULL, 
        CLSCTX_INPROC_SERVER, 
        IID_IWICImagingFactory, 
        reinterpret_cast<void**>(&factory)); 

    factory->CreateDecoderFromFilename(L".png", 
             NULL, 
             GENERIC_READ, 
             WICDecodeMetadataCacheOnLoad, 
             &decoder); 

    decoder->GetFrame(0, &frame); 

    factory->CreateFormatConverter(&converter); 

    converter->Initialize(frame, 
          GUID_WICPixelFormat32bppPBGRA, 
          WICBitmapDitherTypeNone, 
          NULL, 
          0.f, 
          WICBitmapPaletteTypeMedianCut); 

    target->CreateBitmapFromWicBitmap(frame, 0, ppBitmap); 
} 

ID2D1HwndRenderTargetがそのように作成されます。

ID2D1Factory* factory; 
ID2D1HwndRenderTarget* target; 

D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory); 

factory->CreateHwndRenderTarget(
    D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_HARDWARE, 
           D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)), 
    D2D1::HwndRenderTargetProperties(hwnd, D2D1::SizeU(width, height)), 
    &target); 
+0

[MCVE](http://stackoverflow.com/help/mcve)の方法でコードを表示してください。 –

答えて

2

CreateBitmapFromWicBitmapは、最初のパラメータとしてconverter、ないframe期待しています。

CLSID_WICImagingFactory1の代わりにCLSID_WICImagingFactoryを使用してください。コンパイラは正しい値を選択します。私の場合はそれを選ぶCLSID_WICImagingFactory2

IWICImagingFactory* factoryの変数名は同じ名前のグローバル変数を隠しています。これはおそらくエラーの原因ではありませんでしたが、それを変更する方が良いです...

ハンドルを解放する必要があります。

HRESULT LoadBitmapFromFile(const wchar_t *filename, ID2D1HwndRenderTarget* target, ID2D1Bitmap** pBitmap) 
{ 
    HRESULT hr = S_FALSE; 
    IWICImagingFactory* wic_factory = NULL; 
    IWICBitmapDecoder* decoder = NULL; 
    IWICBitmapFrameDecode* frame = NULL; 
    IWICFormatConverter* converter = NULL; 

    hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void**>(&wic_factory)); 
    if FAILED(hr) goto clenaup; 

    hr = wic_factory->CreateDecoderFromFilename(filename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &decoder); 
    if FAILED(hr) goto clenaup; 

    hr = decoder->GetFrame(0, &frame); 
    if FAILED(hr) goto clenaup; 

    hr = wic_factory->CreateFormatConverter(&converter); 
    if FAILED(hr) goto clenaup; 

    hr = converter->Initialize(frame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); 
    if FAILED(hr) goto clenaup; 

    hr = target->CreateBitmapFromWicBitmap(converter, 0, pBitmap); 
    if FAILED(hr) goto clenaup; 

clenaup: 
    safe_release(decoder); 
    safe_release(converter); 
    safe_release(frame); 
    safe_release(wic_factory); 
    return hr; 
} 

CoInitializeEx(0, COINIT_MULTITHREADED)は、初期化で1回呼び出すことができます。

ID2D1Factory* factory; 
ID2D1HwndRenderTarget* target; 

void initialize(HWND hwnd) 
{ 
    CoInitializeEx(0, COINIT_MULTITHREADED); 

    RECT rc; 
    GetClientRect(hwnd, &rc); 

    D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory); 
    factory->CreateHwndRenderTarget(
     D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_HARDWARE, 
     D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)), 
     D2D1::HwndRenderTargetProperties(hwnd, D2D1::SizeU(rc.right, rc.bottom)), 
     &target); 
} 

void on_render() 
{ 
    target->BeginDraw(); 
    target->Clear(D2D1::ColorF(D2D1::ColorF::White)); 

    ID2D1Bitmap* pBitmap = NULL; 
    if (SUCCEEDED(LoadBitmapFromFile(L"filename.png", target, &pBitmap))) 
    { 
     D2D1_SIZE_F size = pBitmap->GetSize(); 
     target->DrawBitmap(pBitmap, D2D1::RectF(0, 0, size.width, size.height)); 
     safe_release(pBitmap); 
    } 

    target->EndDraw(); 
} 
+0

CreateBitmapFromWicBitmap()の引数の問題に気づいたことに多くの感謝をします。私はそれを見つけたことがないでしょう。 しかし、私は別のものを見つけました。 CLSID_WICImagingFactory1をCLSID_WICImagingFactoryに変更すると、CoCreateInstance()はREGDB_E_CLASSNOTREGを返します。 – Avert

+0

です。 'CLSID_WICImagingFactory' [link](http://stackoverflow.com/a/16699299/4603670)に関する情報があります。私はVS2015のWindows 10で、 'CLSID_WICImagingFactory1'と' CLSID_WICImagingFactory2'の両方がうまく動作します。 –