如果您查看如何TDirect2DCanvas
实现绘制图形对象,您会发现它通过此例程进行路由。
procedure TDirect2DCanvas.StretchDraw(const Rect: TRect; Graphic: TGraphic;
Opacity: Byte);
var
D2DBitmap: ID2D1Bitmap;
D2DRect: TD2DRectF;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.Assign(Graphic);
D2DBitmap := CreateBitmap(Bitmap);
D2DRect.Left := Rect.Left;
D2DRect.Right := Rect.Right;
D2DRect.Top := Rect.Top;
D2DRect.Bottom := Rect.Bottom;
RenderTarget.DrawBitmap(D2DBitmap, @D2DRect, Opacity/255);
finally
Bitmap.Free;
end;
end;
让我们取消选择所涉及的步骤:
- 创建一个临时位图。
- 将图形复制到该位图中。
- 创建一个
ID2D1Bitmap
并将临时位图复制到其中。
- 将其绘制
ID2D1Bitmap
到渲染目标上。
这看起来已经非常低效了。当然,调用这个函数传入 aTBitmap
并无缘无故地制作副本会很尴尬。
当您尝试混合两个不同的图形框架时,这种事情是很难避免的。您的图像列表是基于 GDI 的,因此当您尝试将其发送到 Direct2D 画布时必然会遇到摩擦。根本无法将 GDI 位图直接传递到 Direct2D 画布,它们必须首先转换为 Direct2D 位图。
如果性能对您来说很重要,那么您不应该从图像列表开始。当您从 GDI 图像列表中提取位图,然后将其转换为等效的 Direct2D 对象时,这将不可避免地产生成本ID2D1Bitmap
。
为了获得最佳性能,请勿使用图像列表。从图像列表中提取每个图像并用于TDirect2DCanvas.CreateBitmap
获取 Direct2D 位图,ID2D1Bitmap
. 存储这些而不是图像列表。然后当你需要绘制时,调用DrawBitmap
,RenderTarget
传递一个ID2D1Bitmap
.