2012-07-12 291 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