Рисование глифа TImageList в TDirect2DCanvas

В настоящее время я собираюсь заменить чертежный код для старого компонента из GDI + UniScribe на Direct2D и DirectWrite (преемники).

Пока что переход был прямым, так как большую часть времени все, что мне нужно было сделать, это заменить вызовы Canvas (класс TCanvas) на пользовательский экземпляр FDirect2DCanvas (класс TDirect2DCanvas, из модуля Direct2D).

К сожалению, не все так просто при попытке нарисовать глиф из экземпляра TImageList на FDirect2DCanvas, так как метод draw предназначен только для TCanvas, а не для довольно общего TCustomCanvas (который является предком как TCanvas, так и TDirect2DCanvas).

Решением этой дилеммы было бы нарисовать глиф TImageList во временную битовую карту и нарисовать его в TDirect2DCanvas. Тем не менее, я боюсь, что это, вероятно, сильно снизит производительность рисования.

Кто-нибудь до сих пор делал это? Какие варианты у меня есть?

1 ответ

Решение

Если вы посмотрите, как рисование графических объектов 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 и сделать копию без уважительной причины.

Такого рода вещи трудно избежать, когда вы пытаетесь смешать две разные графические рамки. Ваш список изображений основан на GDI, и поэтому он может столкнуться с трениями при попытке отправить его на холст Direct2D. Просто невозможно передать битовые карты GDI непосредственно на холст Direct2D, их нужно сначала преобразовать в битовые карты Direct2D.

Если для вас важна производительность, то вам не следует начинать со списка изображений. Это неизбежно повлечет за собой затраты, когда вы извлекаете растровое изображение из списка изображений GDI, а затем конвертируете его в эквивалентный объект Direct2D, ID2D1Bitmap,

Чтобы достичь оптимальной производительности, не работайте со списками изображений. Извлеките каждое изображение из списка изображений и используйте TDirect2DCanvas.CreateBitmap чтобы получить растровое изображение Direct2D, ID2D1Bitmap, Храните их, а не список изображений. Затем, когда вам нужно нарисовать, позвоните DrawBitmap на RenderTarget, передавая ID2D1Bitmap,

Другие вопросы по тегам