AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Delphi FMX: Schnelles zeichnen gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

FMX: Schnelles zeichnen gesucht

Ein Thema von Sherlock · begonnen am 24. Nov 2016 · letzter Beitrag vom 1. Dez 2016
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#1

FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 11:12
Hallo zusammen,

ich arbeite an einem Projekt, bei dem ich Messwerte eines externen Gerätes auf dem Bildschirm plotten muss. Es gibt dabei folgende Rahmenbedingungen:
es kommen vier Messungen mit jeweils drei Werten pro Sekunde rein - angezeigter Maßstab ist 1cm/Minute
  • die Messung kann auch mal ein bis zwei Tage dauern
  • es sollte möglich sein flüssig hin und her zu scrollen
  • es gibt ein Aktualisierungsintervall, das derzeit bei 6 Sekunden liegt, eventuell später auf 3 reduziert wird
Bisher bin ich wie folgt vorgegangen:
  • ich habe einen Thread, der die Messdaten abholt, Intervall 5s, Abholdauer 1s
  • ich habe einen weiteren Thread, der die kompletten Messdaten in zwei Bitmaps immer wieder neu zeichnet, sobald eine Aktualisierung der Daten anliegt und die Images auf der Oberfläche aktualisiert
Das läuft soweit so gut. Nur stellt sich heraus, daß das Neuzeichnen keine so gute Idee ist. Ab ca 30 Minuten Messdauer, benötigt das Zeichnen mehr Zeit als das Holen der Daten, und es wird immer langsamer. Also habe ich zumindest da einen Flaschenhals. Ich zeichne wie folgt (vereinfacht und aufs wesentliche reduziert, vermutlich nicht compilierbar):
Delphi-Quellcode:
procedure TCTGGrid.PaintFHR(aBitmap: TBitmap);
var
  rowList : TStringList;
  i : Integer;
  GID1Path : TPathData;
  GID2Path : TPathData;
  myX, myY : Single;
begin
  if aBitmap.Canvas.BeginScene then
    try
      GID1Path := TPathData.Create;
      GID2Path := TPathData.Create;
      try
        // In der fValuelist stehen alle Messwerte als Stringliste zur Verfügung. Im Prinzip ist
        // ist das eine CSV-Datei, in eine Stringliste eingelesen.
        for i := 0 to fValueList.Count - 1 do
        begin
          // Methoden aufrufen, die aus einem Zeitstempel die X-Koordinate und
          // aus einem Messwert die y-Koordinate errechnen. Ich bezweifle, daß die zeitkritisch
          // sind. Der Aufruf ist auch nur exemplarisch zu verstehen.
          myX := ConvertTimeToXCoord(StrToFloatDef(fvaluelist[i][keyTimeOffset], 0, fs));
          myY := ConvertBPMToYCoord(StrToFloatDef(fvaluelist[i][aGID1Key], 0, fs));
          GID1Path.LineTo(Pointf(myX, myY));
          myY := ConvertBPMToYCoord(StrToFloatDef(fvaluelist[i][aGID2Key], 0, fs));
          GID2Path.LineTo(Pointf(myX, myY));
        end;
        aBitmap.Canvas.Stroke.Dash := TStrokeDash.Solid;
        aBitmap.Canvas.Stroke.Color := claBlack;
        aBitmap.Canvas.StrokeThickness := 1;
        aBitmap.Canvas.DrawPath(GID1Path, 1);
        aBitmap.Canvas.Stroke.Color := claBlue;
        aBitmap.Canvas.DrawPath(GID2Path, 1);
      finally
        GID1Path.Free;
        GID2Path.Free;
      end;
    finally
      aBitmap.Canvas.EndScene;
    end;
Für eine Stunde dauert das mehr als 10 Sekunden... das ist zu langsam für meinen Anwendungsfall.

Frage eins ist jetzt: Ist es möglich hier etwas zu beschleunigen? Was für Optionen gibt es? Kann ich vielleicht ein bestehendes Image verbreitern und ergänzen? So daß also nur meine 6 Sekunden Intervalle neu zu zeichnen sind, was eine Sache von Millisekunden ist.

Frage zwei: Wie überkomme ich die Bitmapgrößenbeschränkung? Die maximale Breite ist schnell erreicht.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann

Geändert von Sherlock (24. Nov 2016 um 11:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#2

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 11:22
Das wird für jeden Refresh neu gemalt?
* vorher malen und das fertige Bild auf's Canvas malen nutzen

* StringList und die Stringkonvertierungen weg -> eine TList<> mit den Floats
* und diese Floats schon vorher mit Convert###To#Coord konvertieren
* oder die TPathData vorher generieren und dann nur noch auf's Canvas malen
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#3

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 11:27
OK, mir ist während des Schreibens auch gekommen, daß die Konvertierung eventuell doch nicht so schnell gehen könnte wie gedacht. Da gehe ich sofort ran. Ist insgesamt ja auch schöner dann. Danke.

Was das angeht
* vorher malen und das fertige Bild auf's Canvas malen nutzen
...
* oder die TPathData vorher generieren und dann nur noch auf's Canvas malen
So denke ich das ich das tue... also der Thread zeichnet die Bitmap, und wenn er damit durch ist wird die Bitmp auf das Image in der Anwendung "synchronisiert". Nur im Thread braucht es schon verdammt lange die Bitmap zu malen, das haben Zeitmessungen ergeben. :\

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 11:34
Es gab kürzlich mal einen ähnlichen Thread: http://www.delphipraxis.net/190798-[fmx]-eigene-komponente-aufbau-performance.html

Ich würde aus der Datenmenge immer den "sichtbaren Bereich" ermitteln und nur den als Grafik berechnen.
Eine Scrollbar dient dann dazu, den sichtbaren Ausschnitt auszuwählen.

Oder habe ich Dich falsch verstanden?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#5

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 11:39
Im Prinzip richtig verstanden, ich möchte aber "weich" scrollen können, vor allem auf mobilen Devices. Darum ein Bild so groß wie möglich mit so vielen Daten wie möglich...

Bin aber jetzt gerade schonmal dabei die Datenstruktur zu optimieren, um die Stringkonvertierungsaufrufe beim zeichnen zu eliminieren... wie blöd, das ich das nicht selbst gesehen habe .

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann

Geändert von Sherlock (24. Nov 2016 um 13:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#6

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 11:41
Ich bin ja immer geneigt, Dinge zu nehmen, die schon da sind. Hier würde ich mal einfach das in Delphi mitgelieferte TChart mit einer FastLine-Series in den Ring werfen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#7

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 13:18
Erstelle dir vorher mehrere TPath, immer ausschnittsweise, also ideal jeweils so groß oder halb so groß, wie die Anzeige breit ist.
Dann brauchst du nur noch jeweils die TPath "live" zeichnen zu lassen, die grade sichtbar sind.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 14:21
Ab 30 Minuten ist die Anzahl der Messwerte in fValueList zuviel.
Wie schon von stahli vorgeschlagen anstatt von for i := 0 to fValueList.Count - 1 do einfach von for i := MesswertVomBeginnDesSichtbarenBereichs to MesswertVomEndeDesSichtbarenBereichs do .
Das ist schnell und wird auch auf mobilen Devices gut funktionieren. Bei denen kommst du mit deinem Ansatz eh schnell ans Ende.
Korrigiere mich wenn ich mich irre, aber bei steigender Anzahl der Messwerte werden doch eh die meisten Messwerte auf die gleichen Pixel gezeichnet, oder?
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#9

AW: FMX: Schnelles zeichnen gesucht

  Alt 24. Nov 2016, 21:42
Hallo liebe Leute, ich stehe vor dem prinzipiell gleichen Problem und hätte dazu vielleicht eine eigene Anfrage gestartet, so melde ich mich jetzt aber erstmal hier.

Um die FMX-Graphik zu beschleunigen, gab mir ein hilfreiches DP-Mitglied folgenden Hinweis:

"Du must FMX wie eine Game-Engine programmieren...
Delphi-Quellcode:
TThread.Synchrionize(NIL,Procedure
begin
Form.BeginUpdate
Form.Image1.Bitmap.Assign(NewBitmap)
Form.EndUpdate
end
(Teil eines Threads der wartet bis alles fertig ist)

Somit machst Du locker 1000 FPS Fullscreen Images..."

Leider bekam ich aus ihm nicht mehr herausgekitzelt.

Hat jemand ein funktionierendes FMX-Graphik-Beispielprojekt oder kann das Zitat noch ein wenig ergänzen, bitte?

Zwar kenne ich mich mit Threadprogrammierung ein kleines bißchen aus, jedoch längst nicht soviel, daß mir nun genau klar ist, was zu programmieren ist.

Ergänzung: Das mit dem Image auf dem Formular ist inzwischen auch geklärt.

Geändert von Delphi-Laie (24. Nov 2016 um 22:09 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.095 Beiträge
 
Delphi 12 Athens
 
#10

AW: FMX: Schnelles zeichnen gesucht

  Alt 25. Nov 2016, 08:59
Hast du das denn mal versucht mit z.B. zwei festen FullScreen Images im Wechsel ?
Welche FPS bekommst du da raus, das wäre ja der BestCase.
1. Das wäre das reine Bitmap-Schreiben.

Dazu käme ja noch das Zeichnen des Bitmaps, was wohl i.d.R. länger als 1ms dauern wird gerade bei
komplexen Daten.
2. Das wäre das Erzeugen des Hintergrundbildes

Ich denke 1. + 2. wird unter 1000FPS liegen, es sei denn das es wirklich nur um einzelne, oder vorberechnete Bitmaps geht.
Wäre aber schön wenn ich mich da irre.

Rollo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz