【发布时间】:2015-11-03 18:11:55
【问题描述】:
我需要在另一个位图的画布(主位图)上绘制旋转位图。但我不知道怎么做。
我尝试使用 TBitMap.Rotate 方法旋转位图,然后使用 TCanvas.DrawBitmap 方法将其绘制在主 BitMap 上,但这需要很多时间(我需要绘制大约 100 个不同角度的相同位图):
- 调整 BMP 大小
- 旋转 BMP
- 在另一个画布上绘图
如何在没有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);
但添加了 Angle: single 参数
安卓。 FMX。
谢谢。
【问题讨论】:
-
这里是使用扫描线efg2.com/Lab/ImageProcessing/Unit7.TXT的位图旋转示例
-
@JasperSchellingerhout 它只有 180、90 和 270。我需要旋转 12.5、186.23 等小数角度。
-
您需要什么速度以及图像的分辨率和位深度是多少?瓶颈是什么?调整目标图像的大小应该是快速旋转只是复制像素+旋转变换,这需要:1x
cos,1xsin4x*和 2x+/-在 FPU 然后 2 次转换为int应该足够快(如果你也使用双线性过滤,它会慢一点但不多)你应该循环遍历所有目标像素而不是源像素,以避免输出中的空洞。 -
您可以通过将 ScanLine[] 调用降至最低来显着加快这一速度,另请参阅Graphics::TBitmap 另外我希望您同时调整 x、y 轴的大小,而不是一一调整 ...
-
@Spektre 帖子已更新
标签: delphi graphics firemonkey delphi-xe7