2017-06-15 11 views
2

現在、GDI + UniScribeの古いコンポーネントの描画コードをDirect2DとDirectWrite(後継者)に置き換えようとしています。TDirect2DCanvasにTImageListグリフを描画する

私がする必要があるのは、Canvas(クラスTCanvas)への呼び出しをカスタムFDirect2DCanvasインスタンス(ユニットDirect2DからのクラスTDirect2DCanvas)に置き換えるだけだったので、これまでの移行は簡単でした。

残念ながら、TImageListインスタンスからグリフをFDirect2DCanvasに描画しようとすると、描画メソッドがTCanvasのみで、TCustomCanvas(TCanvasとTCanvasの両方の祖先ではありません)が意味を持ちます。 TDirect2DCanvas)。

このジレンマの解決策は、TImageListグリフを一時ビットマップに描画し、これをTDirect2DCanvasに描画することです。しかし、これはおそらく描画性能を大きく低下させる恐れがあります。

今までこれまで行った人はいますか?どのようなオプションがありますか?

答えて

2

図形グラフィックオブジェクト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; 

のは、必要な手順を選択解除してみましょう:

  1. は、一時的なビットマップを作成します。
  2. グラフィックをそのビットマップにコピーします。
  3. ID2D1Bitmapを作成し、一時ビットマップをコピーします。
  4. レンダーターゲットにID2D1Bitmapを描画します。

これは既にかなり非効率的です。確かに、この関数をTBitmapに渡して呼び出すのは間違いありません。

2つの異なるグラフィックスフレームワークをブレンドしようとすると、この種のことは避けがたいです。あなたのイメージリストはGDIベースであり、Direct2Dキャンバスに送信しようとすると摩擦が発生します。 GDIビットマップを直接Direct2Dキャンバスに渡す方法はないため、まずDirect2Dビットマップに変換する必要があります。

パフォーマンスが重要な場合は、画像リストから始めるべきではありません。ビットマップをGDIイメージリストから抽出し、それを対応するDirect2DオブジェクトID2D1Bitmapに変換すると、必然的にコストがかかります。

最適なパフォーマンスを得るには、イメージリストを使用しないでください。イメージリストから各イメージを抽出し、TDirect2DCanvas.CreateBitmapを使用してDirect2DビットマップID2D1Bitmapを取得します。イメージリストではなく、これらを保存します。描画する必要があるときは、RenderTargetDrawBitmapを呼び出し、ID2D1Bitmapを渡します。

関連する問題