如果你看一下如何繪製圖形對象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
繪製到渲染目標上。
這看起來已經非常低效。當然,將這個函數傳遞給TBitmap
並且沒有正當理由複製這個函數會很糟糕。
雖然當您嘗試混合兩個不同的圖形框架,但這種事情很難避免。您的圖像列表基於GDI,當您嘗試將其發送到Direct2D畫布時,會受到摩擦。沒有辦法將GDI位圖直接傳遞給Direct2D畫布,必須先將其轉換爲Direct2D位圖。
如果表現對你至關重要,那麼你不應該從圖像列表開始。當您從GDI圖像列表中提取位圖時,這將不可避免地產生成本,然後將其轉換爲等效的Direct2D對象ID2D1Bitmap
。
爲了實現最佳性能,請不要使用圖像列表。從圖像列表中提取每個圖像並使用TDirect2DCanvas.CreateBitmap
獲取Direct2D位圖,ID2D1Bitmap
。存儲這些而不是圖像列表。然後,當你需要畫畫時,請致電DrawBitmap
RenderTarget
,傳遞ID2D1Bitmap
。