在FireMonkey中绘制像素的最快方法

我做了以下代码:

procedure TForm15.Button1Click(Sender: TObject);
var
  Bitmap1: TBitmap;
  im: TImageControl;
  Color: TColor;
  Scanline: PAlphaColorArray;
  x,y,i: Integer;
begin
  for i:= 1 to 100 do begin
    im:= ImageControl1;
    Bitmap1:= TBitmap.Create(100,100);
    try
      for y:= 0 to 99 do begin
        ScanLine:= Bitmap1.ScanLine[y];
        for x:= 0 to 99 do begin
          ScanLine[x]:= Random(MaxInt);
        end;
      end;
      ImageControl1.Canvas.BeginScene;
      ImageControl1.Canvas.DrawBitmap(Bitmap1, RectF(0,0,Bitmap1.Width, Bitmap1.Height)
                                     ,im.ParentedRect,1,true);
      ImageControl1.Canvas.EndScene;
    finally
      Bitmap1.Free;
    end;
  end;
end;

有没有更快的方式在Firemonkey中绘制像素?
我的目标是使用康威的生活游戏制作演示程序。


所有的时间都花在执行这两行代码上:

ImageControl1.Canvas.BeginScene;
ImageControl1.Canvas.EndScene;

您可以删除所有与位图和实际绘制位图的代码一起工作的代码,这对运行时没有什么影响。 换句话说,瓶颈是场景代码而不是位图代码。 我认为你无法优化它。

我的测试代码如下所示:

Stopwatch := TStopwatch.StartNew;
for i:= 1 to 100 do begin
  ImageControl1.Canvas.BeginScene;
  ImageControl1.Canvas.EndScene;
end;
ShowMessage(IntToStr(Stopwatch.ElapsedMilliseconds));

这与你的代码有相同的时间,在我的机器上是1600ms。 如果您删除了BeginSceneDrawBitmapEndScene调用,那么您的代码在我的机器上以3ms运行。


这是一个更快的方法来做到这一点:

     procedure TForm2.Button1Click(Sender: TObject);
     var i,j: integer;
     begin
       for i := 0 to 200 do
       for j := 0 to 200 do ImageControl1.Bitmap.ScanLine[i][j]:=Random(Maxlongint);
       ImageControl1.Bitmap.BitmapChanged;
     end;

快速和优化!...


你可以像这样优化你的代码:

procedure TForm15.Button1Click(Sender: TObject);
var
  Bitmap1: TBitmap;
  im: TImageControl;
  Color: TColor;
  ScanLine: PAlphaColorArray;
  x,y,i: Integer;
begin
  Bitmap1:= TBitmap.Create(100,100);
  try
    for i:= 1 to 100 do begin
      im:= ImageControl1;
      Scanline := PAlphaColorArray(Bitmap1.StartLine);
      for x := 0 to Bitmap1.Width * Bitmap1.Height do
        ScanLine[x] := Random(MaxInt);
      ImageControl1.Canvas.BeginScene;
      ImageControl1.Canvas.DrawBitmap(Bitmap1, RectF(0,0,Bitmap1.Width, Bitmap1.Height)
                                     ,im.ParentedRect,1,true);
      ImageControl1.Canvas.EndScene;
   end;
 finally
   Bitmap1.Free;
 end;
end;

删除:

  • finally在循环中调用try

  • 在循环中创建TBitmap

  • 调用TBitmap.ScanLine方法

  • 链接地址: http://www.djcxy.com/p/10369.html

    上一篇: Fastest way to draw pixels in FireMonkey

    下一篇: this.domNode is null