将Direct2D的ID2D1HwndRenderTarget转为ID2D1Bitmap时遇参数错误
1. 像素格式/Alpha模式不兼容
你创建ID2D1Bitmap时指定了D2D1_ALPHA_MODE_PREMULTIPLIED,但ID2D1HwndRenderTarget默认的Alpha模式是D2D1_ALPHA_MODE_IGNORE(窗口渲染目标通常针对不透明场景)。当源RenderTarget和目标Bitmap的Alpha模式或像素格式不匹配时,CopyFromRenderTarget会返回E_INVALIDARG。
解决方法:创建Bitmap时直接复用RenderTarget的像素格式和Alpha模式,避免硬编码:
D2D1_PIXEL_FORMAT rtPixelFormat = target->GetPixelFormat(); D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties( rtPixelFormat, target->GetDpiX(), target->GetDpiY() );
2. DPI不匹配
你硬编码了Bitmap的DPI为96.0f,但ID2D1HwndRenderTarget的DPI会跟随系统显示设置(比如高DPI屏幕下可能是120、144等)。DPI不匹配会导致逻辑尺寸与像素尺寸的映射错误,复制时的区域参数不符合要求。
解决方法:直接获取RenderTarget的DPI赋值给Bitmap属性,参考上面的代码示例。
3. RenderTarget处于未完成的绘制状态
如果调用CopyFromRenderTarget前,ID2D1HwndRenderTarget已经调用BeginDraw()但未执行EndDraw(),此时RenderTarget处于绘制中状态,无法作为源被复制,会触发参数无效错误。
解决方法:确保复制前完成当前绘制周期:
// 先结束当前绘制 target->EndDraw(); // 执行复制操作 hr = src_bitmap->CopyFromRenderTarget( &destPoint, target, &srcRect ); // 若后续需继续绘制,重新调用BeginDraw target->BeginDraw();
4. 代码笔误导致参数未正确初始化
你的代码里定义了D2D1_BITMAP_PROPERTIES props;,但后续赋值用的是bitmapProperties(变量名不一致),这会导致Bitmap属性未正确初始化,创建的Bitmap参数非法,进而引发复制失败。
修正方法:统一变量名:
D2D1_BITMAP_PROPERTIES props; props.pixelFormat = D2D1::PixelFormat( DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED ); props.dpiX = 96.0f; props.dpiY = 96.0f;
内容的提问来源于stack exchange,提问作者kinton

