Autor Beitrag
hjl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 2

Windows 10 Enterprise (64 Bit)
Delphi 7, Delphi XE2, Delphi Berlin (10.1), Delphi Tokyo (10.2)
BeitragVerfasst: Do 13.08.20 10:50 
In einer vektorgrafischen Anwendung (64 Bit für Windows 10) habe ich ein Problem.
Normalerweise funktioniert es sehr gut, doch in einem Fall möchte ich eine ungewohnt große Stringdatei (*.str) laden.
Es geht darum, 3,1 Mio. Punkte darzustellen, in einer TBitmap auf Canvas.
Mein Monitor hat mit 1680 x 1050 Pixel nur 1,7 Mio. Pixel, mein Rechner hat 32 GB RAM.
Das Programm kann aber auch Ausschnitte zeigen, beim Laden wird jedoch zuerst immer das ganze Bild gezeigt.
Auch ein ähnliches, käuflich erworbenes Programm konnte die Datei nicht anzeigen.

Das Problem ist, die Anzeige auf dem Bildschirm funktioniert nur im Debugging-Betrieb von Delphi 10.2 (Tokyo).
Lasse ich das Programm als Exe (Debug oder Release) laufen, bekommt es die Anzeige gar nicht hin.
Woran kann das liegen?
Ist Abhilfe möglich?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18871
Erhaltene Danke: 1660

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.08.20 12:06 
Ohne Details zur Implementierung oder idealerweise einem kleinen Testprojekt wird es schwierig dazu etwas zu sagen...

Wie hoch ist denn die Speicherauslastung der Anwendung?

Wird vielleicht einfach nur einmalig auf das Canvas des Formulars gezeichnet statt im OnPaint und ggf. mit TPaintbox oder so etwas?
hjl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 2

Windows 10 Enterprise (64 Bit)
Delphi 7, Delphi XE2, Delphi Berlin (10.1), Delphi Tokyo (10.2)
BeitragVerfasst: Do 13.08.20 12:26 
Es wird eine Datei geladen und dann gezeichnet.

Das wären einige Statements:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
ImgStr.Canvas.Create;

ImgStr.Width                 := ClientWidth;
ImgStr.Height                := ClientHeight;
ImgStr.Picture.Bitmap        := TBitmap.Create;
ImgStr.Picture.Bitmap.Width  := ClientWidth;
ImgStr.Picture.Bitmap.Height := ClientHeight;

ImgStr.Canvas.Rectangle(00, ClientWidth, ClientHeight);

ImgStr.Brush.Style := bsClear;

ImgStr.Brush.Color := RScala.Color(iFF);
ImgStr.Pen.Style := psSolid;
ImgStr.Pen.Color := iColor;
ImgStr.Pen.Width := iWidth;
ImgStr.Polygon(Polygon);    

ImgStr.MoveTo(iRWs,iHWs);

ImgStr.LineTo(iRWs,iHWs);


Moderiert von user profile iconTh69: Delphi-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4279
Erhaltene Danke: 917

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Do 13.08.20 12:53 
Also wird nur temporär gezeichnet, d.h. du mußt das, wie von jaenicke schon geschrieben, im OnPaint-Ereignis ausführen, s.a. Den Bildschirm aktualisieren.

Edit: Und nach dem Laden dann Refresh aufrufen.
hjl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 2

Windows 10 Enterprise (64 Bit)
Delphi 7, Delphi XE2, Delphi Berlin (10.1), Delphi Tokyo (10.2)
BeitragVerfasst: Do 13.08.20 14:28 
Zuerst muss ich mal gestehen, dass ich in meiner Ausführung einen Fehler gemacht habe:
alles, was unterhalb des Rectangle-Statement steht, müsste eigentlich mit ImgStr.Canvas. beginnen, da sie in einer Prozedur stehen, wo die Canvas als Parameter übergeben wird, dort habe die Canvas einfach ImgStr genannt - das war wohl nicht so gut. Diese Prozedur wird auch für Exports nach JPG, TIF, usw. verwendet.

Das mit dem Refresh erscheint mir klar, aber was ist mit dem OnPaint? Vom Formular?

Vielleicht sollte ich auch noch erwähnen, dass die zu ladende Datei im selben Programm vom Benutzer im üblichen Windows-Dateiauswahlmenü ausgewählt wird. Das geht so
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if OpenDialog1.Execute then begin 
  {$ Ermitteln des gesamten Dateipfades }
  {$ Laden der Grafik }
  {$ Anzeigen der Grafik }
end;

So weit ist es ereignisgesteuert.
Wie passt nun OnPaint hier rein? Und welches OnPaint?

Dann verstehe ich noch nicht, was dies mit der stark vergrößerten Datenmenge zu tun hat.
Bei "normalgroßen" Dateien mit bis zu 1,3 Mio. Punkten hat es immer noch funktioniert.

Moderiert von user profile iconTh69: Delphi-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18871
Erhaltene Danke: 1660

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.08.20 14:34 
user profile iconhjl hat folgendes geschrieben Zum zitierten Posting springen:
Dann verstehe ich noch nicht, was dies mit der stark vergrößerten Datenmenge zu tun hat.
Bei "normalgroßen" Dateien mit bis zu 1,3 Mio. Punkten hat es immer noch funktioniert.
Ein TImage (vermute ich mal aufgrund des Namens) ist hier ungünstig. Besser ist es die Daten in einer Bitmap im Speicher zu lassen und dann den Inhalt oder den gewünschten Ausschnitt in die Anzeige zu kopieren.

Das hatte Michael hier als Beispiel in einer TPaintbox gemacht:
michael-puff.de/Prog...ffScreenBitmap.shtml

Für diesen Beitrag haben gedankt: hjl
hjl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 2

Windows 10 Enterprise (64 Bit)
Delphi 7, Delphi XE2, Delphi Berlin (10.1), Delphi Tokyo (10.2)
BeitragVerfasst: Do 13.08.20 14:43 
Danke für den Hinweis!
Das schaue ich erst mal in Ruhe an, wenn ich mehr Zeit dafür habe.