2

質問はこれと非常によく似ていますが、まだ回答がありません。私の質問は、d2dfactory->CreateDxgiSurfaceRenderTarget() からの D2D DXGI RenderTarget があり、そのコンテンツを WIC を使用して画像ファイルに保存したいということです。私はこれこれを読んでいたので、WIC レンダー ターゲットで ID2D1Bitmap を作成し、ID2D1Bitmap::CopyFromRenderTarget() を使用して、保存したい入力レンダー ターゲットからコピーすることはできないようです。さまざまなリソース。ID2D1RenderTarget::CreateSharedBitmap() を使用して思いついたのは次のとおりです。

HRESULT SaveRenderTargetToFile(
    ID2D1RenderTarget* pRTSrc,
    LPCWSTR uri
    )
{
    HRESULT hr = S_OK;

    ComPtr<IWICBitmap> spWICBitmap;
    ComPtr<ID2D1RenderTarget> spRT;
    ComPtr<IWICBitmapEncoder> spEncoder;
    ComPtr<IWICBitmapFrameEncode> spFrameEncode;
    ComPtr<IWICStream> spStream;

    //
    // Create WIC bitmap to save and associated render target
    //

    UINT bitmapWidth = static_cast<UINT>(pRTSrc->GetSize().width + .5f);
    UINT bitmapHeight = static_cast<UINT>(pRTSrc->GetSize().height + .5f);

    HR(m_spWICFactory->CreateBitmap(
        bitmapWidth,
        bitmapHeight,
        GUID_WICPixelFormat32bppPBGRA,
        WICBitmapCacheOnLoad,
        &spWICBitmap
        ));

    D2D1_RENDER_TARGET_PROPERTIES prop = D2D1::RenderTargetProperties();
    prop.pixelFormat = D2D1::PixelFormat(
        DXGI_FORMAT_B8G8R8A8_UNORM,
        D2D1_ALPHA_MODE_PREMULTIPLIED
        );
    prop.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
    prop.usage = D2D1_RENDER_TARGET_USAGE_NONE;
    HR(m_spD2D1Factory->CreateWicBitmapRenderTarget(
        spWICBitmap,
        prop,
        &spRT
        ));

    //
    // Create a shared bitmap from this RenderTarget
    //
    ComPtr<ID2D1Bitmap> spBitmap;
    D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties();
    bp.pixelFormat = prop.pixelFormat;

    HR(spRT->CreateSharedBitmap(
        __uuidof(IWICBitmap),
        static_cast<void*>(spWICBitmap.GetRawPointer()),
        &bp,
        &spBitmap
        ));    // <------------------------- This fails with E_INVALIDARG

    //
    // Copy the source RenderTarget to this bitmap
    //
    HR(spBitmap->CopyFromRenderTarget(nullptr, pRTSrc, nullptr));

    //
    // Draw this bitmap to the output render target
    //

    spRT->BeginDraw();
    spRT->Clear(D2D1::ColorF(D2D1::ColorF::GreenYellow));
    spRT->DrawBitmap(spBitmap);
    HR(spRT->EndDraw());

    //
    // Save image to file
    //

    HR(m_spWICFactory->CreateStream(&spStream));
    WICPixelFormatGUID format = GUID_WICPixelFormat32bppPBGRA;
    HR(spStream->InitializeFromFilename(uri, GENERIC_WRITE));

    HR(m_spWICFactory->CreateEncoder(GUID_ContainerFormatPng, nullptr, &spEncoder));
    HR(spEncoder->Initialize(spStream, WICBitmapEncoderNoCache));
    HR(spEncoder->CreateNewFrame(&spFrameEncode, nullptr));
    HR(spFrameEncode->Initialize(nullptr));
    HR(spFrameEncode->SetSize(bitmapWidth, bitmapHeight));
    HR(spFrameEncode->SetPixelFormat(&format));
    HR(spFrameEncode->WriteSource(spWICBitmap, nullptr));
    HR(spFrameEncode->Commit());
    HR(spEncoder->Commit());
    HR(spStream->Commit(STGC_DEFAULT));

done:
    return hr;
}

このコードに何か問題がありますか? (たくさんあると思います :)) MSDN のどこかで、WIC レンダー ターゲットはソフトウェア モードのみをサポートし、DXGI レンダー ターゲットはハードウェア モードのみをサポートすると書かれています。これが、上記の CreateSharedBitmap() の呼び出しが失敗する理由ですか? では、D2D を使用して DXGI サーフェス コンテンツを画像ファイルに保存するにはどうすればよいですか?

4

2 に答える 2

2
  1. いくつかの制限がありますが、使用できますD3DX11SaveTextureToFile。表面で QI を使用して を取得しID3D11Resourceます。

  2. 同じページでDirectXTex、代替としてライブラリ、CaptureTexture、SaveToXXXFile (XXX は WIC、DDS、または TGA) を推奨しています。それは別のオプションです。

  3. また、サーフェスが GDI 互換として作成されている場合は、IDXGISurface1::GetDC. (IDXGISurface1 を取得するには、IDXGISurface で QI を使用します)。DC をファイルに保存することは、読者の課題として残されています。

のような不可解なリターン コードをサポートするために、 Debug Layerを使用することを忘れないでくださいE_INVALIDARG

于 2014-02-14T19:40:24.657 に答える