Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Zeichnen eines Plots beschleunigen (TImage) (https://www.delphipraxis.net/104667-zeichnen-eines-plots-beschleunigen-timage.html)

rawsoul 8. Dez 2007 15:37


Zeichnen eines Plots beschleunigen (TImage)
 
Hallo liebe Gemeinde,

ich möchte ein Array in einem Image plotten. Das ganze geschieht über ein TBitmap, welches nach dem Zeichnen auf das Image assigned wird (BitBlt). Dies verhindert im Vergleich zum direkten Zeichnen auf das Image das flackern und beschleunigt den Vorgang. Trotzdem ist es mir noch zu langsam.
Es wird nämlich sehr of (300 Mal, für jedes Arrayelement) gezeichnet, da ich eine flüssige Bewegung darstellen möchte.

Delphi-Quellcode:
procedure drawgraph(arr:tintarr;image:timage;bmp:tbitmap);
var
  i:integer;
  col:tcolor;
begin
  with bmp do
    begin
      Canvas.Brush.Color:=clbtnface;
      Canvas.Pen.Color:=clblack;
      Canvas.Rectangle(0,0,302,302);
      for i:=0 to 299 do
        begin
          if arr[i]=i then Col:=clgreen else Col:=clred; //Der Sinn hiervon sei mal dahingestellt...
          Canvas.Pixels[i+1,300-arr[i]]:=col;
        end;
    end;
  bitblt(image.Canvas.Handle,0,0,302,302,bmp.Canvas.Handle,0,0,srccopy);
  image.Refresh;
end;
Wie kann ich die Prozedur beschleunigen? Dabei möchte ich jedoch ungern auf TChart oder OGL zurückgreifen.

Grüße,
Frank.

Nuclear-Ping 8. Dez 2007 15:42

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Schau dir mal "ScanLine" an, bzw. such mal danach. Aus dem Kopf weiß ich grad keine Beispiele, damit solltest du das Ganze aber erheblich beschleunigen können.

DGL-luke 8. Dez 2007 15:43

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Delphi-Quellcode:
Canvas.Pixels[i+1,300-arr[i]]:=col;
Das ist der Übeltäter.

Verwende Hier im Forum suchenScanLine oder gehe zu Hier im Forum suchenGraphics32 (http://www.graphics32.org/) über - da hast du dann performance der extraklasse.

rawsoul 8. Dez 2007 17:19

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Danke für die Tipps! Scanline ist in meinem Falle leider noch langsamer - mag auch an mir liegen - und bei der Installation von GR32 hatte ich bisher leider immer Probleme (Visuelle Objekte - z.B. TImage32 sind weder in der Bibliothek aufgelistet, noch kann ich sie dynamisch erstellen).

DGL-luke 8. Dez 2007 17:37

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Hallo,

ja, mit Scanline hast du hier ein Problem, da du auf einzelne Pixel zugreifst, und das ganze nicht zeilenweise abarbeiten kannst.

Hm... erzähl mal, was genau du vor hast... :gruebel:

rawsoul 8. Dez 2007 18:00

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Genau so hatte ich mir das Problem auch gedacht.

Mein Vorhaben liegt darin, einige (vielleicht auch viele :P) Sortieralgorythmen visuell darzustellen. Die x-Achse stellt das Index des Elements dar, die y-Achse den Wert.

DGL-luke 8. Dez 2007 18:09

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Hm. Pixel[] sollte im Prinzip nur MSDN-Library durchsuchenSetPixel wrappen. Eventuell kannst du dir damit die Farbumrechnung und einen Call sparen, was das ganze marginal beschleunigen sollte.

Namenloser 8. Dez 2007 18:17

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Delphi-Quellcode:
procedure drawgraph(arr:tintarr;bmp:tbitmap);
var
  i,x:integer;
  rows: packed array of integer;
  ptr: pcolrec;
  cl1,cl2: tcolrec;
begin
  with bmp do
  begin
    bmp.PixelFormat := pf32bit;
    Canvas.Brush.color := clbtnface;
    Canvas.pen.color := clblack;
    Canvas.Rectangle(0,0,width,height);
    setlength(rows,bmp.Height);
    // tabelle für zeilen erstellen
    for i := bmp.height-1 downto 0 do
      rows[i] := integer(bmp.ScanLine[i]);
    // record für Farbe 1
    cl1.g := 0; cl1.b := 0; cl1.r := 255; cl1.a := 255;
    // record für Farbe 2
    cl2.g := 127; cl2.b := 0; cl2.r := 0; cl2.a := 255;
    x := 4;
    for i:=0 to 300-1 do
    begin
      // PixelPointer berechnen
      //                 <   Y  > < X >
      ptr := pointer(rows[300-arr[i]] + x);
      if arr[i]=i then
        ptr^ := cl2    // grün
      else
        ptr^ := cl1;  // rot
      inc(x,4);
    end;
  end;
end;
Mit dieser Funktion kann man bei 1000 Durchläufen 100ms rausholen... mehr nicht. Das langsamste an der Sache ist Canvas.Rectangle.

//Edit: Falls es wen interessiert:
OHNE Rectangle:
---------------------------
Scanline: 109
Canvas: 219
---------------------------

MIT Rectangle:
---------------------------
Scanline: 437
Canvas: 532
---------------------------
//EditEdit:
Typendeklaration:
Delphi-Quellcode:
  tcolrec = packed record
    b,g,r,a: byte;
  end;
  pcolrec = ^tcolrec;

rawsoul 8. Dez 2007 20:43

Re: Zeichnen eines Plots beschleunigen (TImage)
 
Tausendundeinen Dank an euch drei, schon viel besser :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz