在画布上绘制旋转的位图 [英] Drawing rotated bitmaps on canvas

查看:208
本文介绍了在画布上绘制旋转的位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在另一个位图的画布(主位图)上绘制旋转的位图。但我不知道该怎么做。



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


  1. 调整BMP大小
  2. 旋转BMP

  3. 在另一个画布上绘制

如何立即绘制不带1的旋转位图2步?



示例:

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

执行

{$ R * .fmx}


过程TForm1.FormCreate(Sender:TObject);
begin
MainBMP:= TBitMap.Create;
MainBMP.SetSize(screen.Width,screen.Height);
SomeItem:= TBitMap.Create;
SomeItem.SetSize(50,50);
与SomeItem.Canvas做
开始
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(随机(360)); 

需要16-32 ms。使用此方法:〜8500 ms



我正在寻找一些方法,如

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

但添加了角度:单个参数

Android。 FMX。



谢谢。

解决方案

您应该使用转换 Matrix 而不是<$ c

这可能看起来像:

<$>

p $ p> procedure TForm1.Timer1Timer(Sender:TObject);
var
I:Integer;
R:TRectF;
SaveMatrix:TMatrix;
矩阵: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:=随机(1200);
Matrix.m32:=随机(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;


I need to draw rotated bitmap on an another bitmap's canvas (main Bitmap). But i have no idea how.

I tried to rotate bitmap with TBitMap.Rotate method and then draw it on main BitMap with TCanvas.DrawBitmap method, but it takes a lot of time (i need to draw ~100 same Bitmaps with different angles):

  1. resize BMP
  2. rotate BMP
  3. draw on another canvas

How to immediately draw rotated bitmap without 1 and 2 steps?

Example:

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;

without

buffBMP.Rotate(random(360));

it takes 16-32 ms. With this method: ~8500 ms

I'm searching for some method like

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

but with added Angle: single parametr

Android. FMX.

Thanks.

解决方案

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;

这篇关于在画布上绘制旋转的位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆