I need to convert a Direct2D ID2D1HwndRenderTarget into an ID2D1Bitmap. However, I'm encountering an error with CopyFromRenderTarget. ”Error: E_INVALIDARG One or more arguments are invalid.”
What could be the issue?
using Direct2D 1.0 (include d2d1.h)
HRESULT hr;
ID2D1Factory* factory;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);
ID2D1HwndRenderTarget* target;
D2D1_RENDER_TARGET_PROPERTIES prop{ D2D1::RenderTargetProperties() };
factory->CreateHwndRenderTarget(prop,D2D1::HwndRenderTargetProperties(hwnd,
D2D1::SizeU(static_cast<UINT>(width), static_cast<UINT>(height))), target);
// ID2D1HwndRenderTarget* target
HRESULT hr;
D2D1_SIZE_F size = target->GetSize();
UINT width = static_cast< UINT >( size.width );
UINT height = static_cast< UINT >( size.height );
D2D1_SIZE_U px_size = target->GetPixelSize();
D2D1_BITMAP_PROPERTIES props;
bitmapProperties.pixelFormat = D2D1::PixelFormat( DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED );
bitmapProperties.dpiX = 96.0f;
bitmapProperties.dpiY = 96.0f;
ID2D1Bitmap* src_bitmap;
hr = target->CreateBitmap( px_size, NULL, 0, &props, &src_bitmap );
// Copy the contents of the current drawing target to a bitmap
D2D1_POINT_2U destPoint = D2D1::Point2U( 0, 0 );
D2D1_RECT_U srcRect = D2D1::RectU( 0, 0, px_size.width, px_size.height );
// Error: E_INVALIDARG One or more arguments are invalid.
hr = src_bitmap->CopyFromRenderTarget( &destPoint, target, &srcRect );
An HWND Direct2D Render Target supports various pixel formats. When you create it like you do (passing D2D1::RenderTargetProperties()
) you're implicitly using the DXGI_FORMAT_B8G8R8A8_UNORM
+ D2D1_ALPHA_MODE_IGNORE
parameters.
So you can either change how you create the render target (you can use D2D1_ALPHA_MODE_PREMULTIPLIED
) and don't change the bitmap's pixel format, or change the bitmap's pixel format to D2D1_ALPHA_MODE_IGNORE
.
But the best is to just copy the render target's pixel format like this:
D2D1_BITMAP_PROPERTIES bitmapProperties{}; // use 0 for dpi means auto-adapt
bitmapProperties.pixelFormat = target->GetPixelFormat();