ID2D1HwndRenderTarget::CreateBitmapFromWicBitmap()
ID2D1HwndRenderTarget::CreateBitmapFromWicBitmap()
我正在尝试使用 WIC 从文件中加载图片并使用 Direct2D 在屏幕上显示它。我遵循 MSDN example 但我遇到函数 CreateBitmapFromWicBitmap() 的问题。
无论我在 ID2D1HwndRenderTarget
创建和 IWICFormatConverter::Initialize()
函数调用期间使用 pixel formats 的哪种组合,函数 CreateBitmapFromWicBitmap()
returns 0x88982f80 错误(WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
).
我使用我用于绘图的相同 ID2D1HwndRenderTarget
调用该函数。我应该创建另一个渲染目标吗?
在此link的评论部分中,有人写道CreateBitmapFromWicBitmap()
应该被DXGI表面渲染目标调用。这是否意味着此功能根本无法与 ID2D1HwndRenderTarget
一起使用?
编辑:
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);
CreateBitmapFromWicBitmap
期望 converter
作为第一个参数,而不是 frame
.
使用 CLSID_WICImagingFactory
而不是 CLSID_WICImagingFactory1
。编译器将选择正确的值。在我的例子中,它选择 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)
初始化时可以调用一次
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();
}
我正在尝试使用 WIC 从文件中加载图片并使用 Direct2D 在屏幕上显示它。我遵循 MSDN example 但我遇到函数 CreateBitmapFromWicBitmap() 的问题。
无论我在 ID2D1HwndRenderTarget
创建和 IWICFormatConverter::Initialize()
函数调用期间使用 pixel formats 的哪种组合,函数 CreateBitmapFromWicBitmap()
returns 0x88982f80 错误(WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
).
我使用我用于绘图的相同 ID2D1HwndRenderTarget
调用该函数。我应该创建另一个渲染目标吗?
在此link的评论部分中,有人写道CreateBitmapFromWicBitmap()
应该被DXGI表面渲染目标调用。这是否意味着此功能根本无法与 ID2D1HwndRenderTarget
一起使用?
编辑:
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);
CreateBitmapFromWicBitmap
期望 converter
作为第一个参数,而不是 frame
.
使用 CLSID_WICImagingFactory
而不是 CLSID_WICImagingFactory1
。编译器将选择正确的值。在我的例子中,它选择 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)
初始化时可以调用一次
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();
}