2012-07-12 286 views
4

尝试将ID2D1Bitmap(从ID2D1HwndRenderTarget创建)保存到PNG文件时遇到问题。输出图像只是空白的白色。从函数调用EndDraw()返回的HRESULT是-2003238894。如何将ID2D1Bitmap保存为PNG文件

感谢您的任何帮助。

这里是我的代码:

HRESULT CImageUtil::SaveBitmapToFile(PCWSTR uri,ID2D1Bitmap* pBitmap,ID2D1RenderTarget* pRenderTarget) 
{ 

HRESULT hr = S_OK; 

ID2D1Factory *pD2DFactory = NULL; 
IWICBitmap *pWICBitmap = NULL; 
ID2D1RenderTarget *pRT = NULL; 
IWICBitmapEncoder *pEncoder = NULL; 
IWICBitmapFrameEncode *pFrameEncode = NULL; 
IWICStream *pStream = NULL; 

if (SUCCEEDED(hr)) 
{ 
    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory); 
} 

// 
// Create IWICBitmap and RT 
// 

UINT sc_bitmapWidth = pBitmap->GetSize().width; 
UINT sc_bitmapHeight = pBitmap->GetSize().height; 

if (SUCCEEDED(hr)) 
{ 
    hr = m_pWICFactory->CreateBitmap(
     sc_bitmapWidth, 
     sc_bitmapHeight, 
    GUID_WICPixelFormat32bppPBGRA, 
     WICBitmapCacheOnLoad, 
     &pWICBitmap 
     ); 
} 

if (SUCCEEDED(hr)) 
{ 
    D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(); 
    rtProps.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 
    rtProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; 
    rtProps.usage = D2D1_RENDER_TARGET_USAGE_NONE; 

    hr = pD2DFactory->CreateWicBitmapRenderTarget(
     pWICBitmap, 
    rtProps, 
     &pRT 
     ); 
} 

if (SUCCEEDED(hr)) 
{ 
    // 
    // Render into the bitmap 
    // 
    pRT->BeginDraw(); 

pRT->Clear(D2D1::ColorF(D2D1::ColorF::White)); 


pRT->DrawBitmap(pBitmap); 

    pRT->EndDraw(); 
} 
if (SUCCEEDED(hr)) 
{ 

    // 
    // Save image to file 
    // 
    hr = m_pWICFactory->CreateStream(&pStream); 
} 

WICPixelFormatGUID format = GUID_WICPixelFormat32bppPBGRA; 
if (SUCCEEDED(hr)) 
{ 

    hr = pStream->InitializeFromFilename(uri, GENERIC_WRITE); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = m_pWICFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pEncoder->CreateNewFrame(&pFrameEncode, NULL); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pFrameEncode->Initialize(NULL); 
} 

if (SUCCEEDED(hr)) 
{ 
    hr = pFrameEncode->SetSize(sc_bitmapWidth, sc_bitmapHeight); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pFrameEncode->SetPixelFormat(&format); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pFrameEncode->WriteSource(pWICBitmap, NULL); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pFrameEncode->Commit(); 
} 
if (SUCCEEDED(hr)) 
{ 
    hr = pEncoder->Commit(); 
} 

SafeRelease(&pD2DFactory); 
SafeRelease(&pWICBitmap); 
SafeRelease(&pRT); 
SafeRelease(&pEncoder); 
SafeRelease(&pFrameEncode); 
SafeRelease(&pStream); 

return hr; 
} 

回答

0

你如何知道,如果你有一个错误,因为你刚刚吞下错误并继续,而不是他们来自何处记录?你得到一个非零的hresult,所以首先通过在每个函数调用后添加一个printf或fprintf来确定它来自哪个函数。和你有块中的明显的遗漏:

if (SUCCEEDED(hr)) 
{ 
    // 
    // Render into the bitmap 
    // 
    pRT->BeginDraw(); 

pRT->Clear(D2D1::ColorF(D2D1::ColorF::White)); 


pRT->DrawBitmap(pBitmap); 

    pRT->EndDraw(); 
} 
if (SUCCEEDED(hr)) 

你不用费心在哪里有个分配小时,所以你甚至不知道其中是否有示数出来。显然,Clear()和最终的png编写工作正常,因为你得到一个好文件,所以它是DrawBitmap或失败的位图创建调用之一。

+0

是的,当我这样编码:pRT-> DrawBitmap(pBitmap); hr = pRT-> EndDraw()然后hr = -2003238894。这意味着调用DrawBitmap会出错。如果我注释掉行pRT-> DrawBitmap(...),那么hr = S_OK。 – 2012-07-12 08:20:54

+0

我想这个错误是因为我绘制了不兼容的位图。我使用WIC渲染目标来绘制Hwnd渲染目标的位图。但我不知道如何解决它。 – 2012-07-12 08:39:50

+4

我在此查找错误代码:http://msdn.microsoft.com/en-us/library/windows/desktop/dd370979%28v=vs.85%29.aspx(0x88990012 = D2DERR_WRONG_FACTORY)。看起来问题是pBitmap和pRT不是由相同的ID2D1Factory对象创建的。 – 2012-07-12 22:31:48