Самый быстрый способ рисовать пиксели в FireMonkey - PullRequest
7 голосов
/ 24 января 2012

Я сделал следующий код:

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?
Я стремлюсь сделать демонстрационную программу, используя игру жизни Конвея.

Ответы [ 3 ]

6 голосов
/ 25 января 2012

Все время затрачивается на выполнение этих двух строк кода:

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));

Это время, равное вашему коду, 1600 мс на моей машине.Если вы удалите вызовы BeginScene, DrawBitmap и EndScene, ваш код будет запущен на моей машине через 3 мс.

0 голосов
/ 14 марта 2013

Вот более быстрый способ сделать это:

     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;

Быстрый и оптимизированный! ...

0 голосов
/ 25 января 2012

Вы можете оптимизировать свой код следующим образом:

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;

Удалено:

  • вызов try finally в цикле

  • создание TBitmap в цикле

  • вызов TBitmap.ScanLine метод

...