在 canvas 上绘制旋转位图

Drawing rotated bitmaps on canvas

我需要在另一个位图的 canvas(主位图)上绘制旋转位图。但是我不知道怎么办。

我尝试用 TBitMap.Rotate 方法旋转位图,然后用 TCanvas.DrawBitmap 方法在主位图上绘制它,但这需要很多时间(我需要用不同的方法绘制约 100 个相同的位图角度):

  1. 调整 BMP 大小
  2. 旋转 BMP
  3. 借鉴另一个canvas

如何不经过1步和2步立即绘制旋转位图?

示例:

var
  Form1: TForm1;
  MainBMP: TBitMap;
  SomeItem: TBitMap;
  buffBMP: TBitMap;

implementation

{$R *.fmx}


procedure TForm1.FormCreate(Sender: TObject);
begin
  MainBMP := TBitMap.Create;
  MainBMP.SetSize(screen.Width, screen.Height);
  SomeItem := TBitMap.Create;
  SomeItem.SetSize(50, 50);
  with SomeItem.Canvas do
  begin
    BeginScene;
    FillRect(rectF(0, 0, 50, 50), 5, 20, allCorners, 1);
    EndScene;
  end;
  buffBMP := TBitMap.Create;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i: integer;
  rect, sizeRect: TRectF;
begin
  MainBMP.Canvas.BeginScene;
  MainBMP.Canvas.Clear($FF777777);
  for i := 1 to 10000 do
  begin
    buffBMP.Assign(SomeItem);
    buffBMP.Rotate(random(360));
    sizeRect := rectF(0, 0, buffBMP.Width, buffBMP.Height);
    rect := sizeRect;
    rect.Offset(random(1200), random(600));
    MainBMP.Canvas.DrawBitmap(buffBMP, sizeRect, rect, 1);
  end;
  MainBMP.Canvas.EndScene;
  Form1.Canvas.BeginScene;
  Form1.Canvas.DrawBitmap(MainBMP, ClientRect, ClientRect, 1);
  Form1.Canvas.EndScene;
end;

没有

buffBMP.Rotate(random(360));

需要 16-32 毫秒。使用此方法:~8500 毫秒

我正在寻找类似

的方法
TCanvas.DrawBitmap(const ABitmap: TBitmap; const SrcRect, DstRect: TRectF; const AOpacity: Single; const HighSpeed: Boolean);

但添加了角度:单个参数

Android。 FMX.

谢谢。

您应该在位图上使用变换 Matrix 而不是 Rotate 方法。

这样看起来像:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  I: Integer;
  R: TRectF;
  SaveMatrix: TMatrix;
  Matrix: TMatrix;
begin
  MainBMP.Canvas.BeginScene;
  MainBMP.Canvas.Clear($FF777777);
  SaveMatrix := MainBmp.Canvas.Matrix;
  for I := 1 to 1000 do
  begin
    BuffBMP.Assign(SomeItem);
    R := RectF(0, 0, BuffBMP.Width, BuffBMP.Height);
    Matrix := CreateRotationMatrix(DegToRad(Random(360)));
    Matrix.m31 := Random(1200);
    Matrix.m32 := Random(600);
    MainBMP.Canvas.SetMatrix(Matrix);
    MainBMP.Canvas.DrawBitmap(buffBMP, R, R, 1, True);
  end;
  MainBMP.Canvas.SetMatrix(SaveMatrix);
  MainBMP.Canvas.EndScene;
  Canvas.BeginScene;
  Canvas.DrawBitmap(MainBMP, ClientRect, ClientRect, 1);
  Canvas.EndScene;
end;