在画布

时间:2015-08-11 13:27:14

标签: delphi graphics firemonkey delphi-xe7

我需要在另一个位图的画布(主Bitmap)上绘制旋转的位图。但我不知道如何。

我尝试使用TBitMap.Rotate方法旋转位图,然后使用TCanvas.DrawBitmap方法在主BitMap上绘制,但需要花费大量时间(我需要绘制~100个不同角度的相同位图):

  1. 调整BMP大小
  2. 旋转BMP
  3. 在另一个画布上画画
  4. 如何在没有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 ms

    我正在寻找像

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

    但添加了角度:单参数

    机器人。 FMX。

    感谢。

1 个答案:

答案 0 :(得分:2)

You should use a transformation Matrix instead of the Rotate method on the bitmap.

Such could look like:

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;