[gelöst] Probleme mit Canvas/Image und Ausführung.

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

[gelöst] Probleme mit Canvas/Image und Ausführung.

Beitrag von Erwin »

Hallo Zusammen.

Mir fiel keine bessere Überschrift ein.
Es geht um folgendes, was ich verwirrender weise feststellen musste, bzw. dies ist der Code von einem Button, mit dem ich ein Problem habe:

Code: Alles auswählen

 
procedure TForm1.BildKopierenButtonClick(Sender: TObject);
begin
  BildKopierenButton.Caption:='Starte'// 1
  BildAusschnittImage.Canvas.CopyRect(Rect(0,0,32,32), GrossesImage.Picture.PNG.Canvas, Rect(0,0,32,32))// 2
  BildAusschnittImage.Picture.PNG.TransparentColor:=$FFB27F;  // 3
  BildAusschnittImage.Picture.PNG.Transparent := True// 4
end;
 

Hoffe ich habe alles richtig geschrieben.
Das BildAusschnittImage ist wiederum auf einem Panel, welches wiederum auf einem Panel ist.
Edit: Und dort noch mal in einem weiterem Image. // Fragt lieber nicht, warum ...
Wenn ich dies zum ersten mal ausführe, also auf den Button Clicke, wird nur das Caption geändert (Punkt 1).
Erst beim Zweiten mal wird auch das Bild Kopiert (Punkt 2).
3 und 4 wird überhaupt nicht ausgeführt, bzw. die gewünschte Transparente Farbe wird nicht transparent.
Wenn nur die Code-Zeile 2 vorhanden ist, wird es auch beim ersten mal kopiert.

Wen ich es stattdessen in eine Image kopieren will, das direkt auf dem Formular ist geht beim ersten mal Punkt 1 und 2.
3 und 4 hingegen ... scheint wohl generell nicht zu gehen, oder liegt es an was anderem?

Also für mich ist all das sehr verwirrend? Da kann man sich ja auf gar nichts verlassen?
Zuletzt geändert von Erwin am Fr 29. Jun 2018, 11:00, insgesamt 3-mal geändert.
Lazarus 2.2.0 / FP 3.2.4

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von wp_xyz »

Erwin hat geschrieben:Also für mich ist all das sehr verwirrend? Da kann man sich ja auf gar nichts verlassen?

Gemach, gemach. Graphik ist kompliziert, und es dauert einige Zeit bis man die Grundprinzipien inne hat...

Der Hauptfehler ist m.E., dass du auf dem Canvas des Image zeichnest. Das habe ich hier im Forum schon öfter gesehen, und mir dreht sich jedes Mal der Magen um.Grundregel: auf dem Canvas eines LCL-Controls darf man nur innerhalb eines Paint-Ereignisses zeichnen. Manche Widgetsets unterbinden das direkt, bei anderen wie Windows merkt man das Problem erst, wenn das Fenster neugezeichnet wird (weil zum Beispiel ein aufgepopptes Dialogfenster wieder geschlossen wird) - und dann ist die eigene Kreation weg, denn das OnClick-Ereignis, das auf dem Canvas gezeichnet hat, ist lange vorbei.

Als Folge davon funktioniert auch das mit der Transparenz nicht, denn wenn der Canvas des Image verändert wird kriegt das das PNG natürlich nicht mit.

Schau dir mal das beigefügte Beispiel an. Es macht sicher nicht genau dasselbe, was du willst, aber es kommt in die Nähe.

[EDIT]
Ach ja noch: Meiner Meinung nach ist bei PNG die Transparenz über den Alpha-Kanal realisiert, also das 4.Byte in TColor. nicht durch eine "transparente" Farbe.
Dateianhänge
Bildausschnitt.zip
(9.64 KiB) 116-mal heruntergeladen

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Erwin »

wp_xyz hat geschrieben:
Erwin hat geschrieben:Also für mich ist all das sehr verwirrend? Da kann man sich ja auf gar nichts verlassen?

Gemach, gemach. Graphik ist kompliziert, und es dauert einige Zeit bis man die Grundprinzipien inne hat...

Zu kompliziert. Obwohl ich einiges dazu gelesen habe, geht bis jetzt nirgends klar hervor, wie das geht.
Es sei denn das eine damals, wo man die Bilder hin und her kopieren muss in 1-2 Extra Objekte und Speicher. Ist aber eben zu kompliziert.
Einfaches Ausprobieren zwischen I1.Picturre.PNG und I2.Picture.PNG brachte auch keine Sinnvollen Ergebnisse. Auch etwas, was ich nicht nachvollziehen kann.
Deshalb habe ich auch schon überlegt, das Bild einfach auf Canvas zu zeichnen. Aber das dauert dann wieder recht lange.
Wenn man nicht Grafik/Picture mit Canvas vermischen soll, dann sollte man es einem auch einfacher machen, von Grafik/Picture zu Grafik/Picture zu kopieren.
Und die Lektüren schweigen dazu. Das zu Lazarus und FPC sowieso. Da finde ich gerade mal 10 % dessen, was ich Suche, und fast all diese Ergebnisse findet sich aber auch in Büchern zu Delphi. Welche (zu Delphi) sich ebenfalls beim Grafikkopieren eher ausschweigen, als einem was erklären.
Und dann wundern die sich, wenn man alles umsonst haben 'will'. Die meisten Autoren wollen ja selber auch das Geld haben, ohne ordentlich zu liefern.

Etwas runter kopieren/laden? Ungern. Ich sage sogar zu meiner Mutter, und selbst wenn eine Datei von mir kommt, erst Prüfen, weil woher willst Du wissen, ob ich meine Rechner tatsächlich Virenfrei habe?
Aber bleibt mir wohl nichts anderes übrig?
Lazarus 2.2.0 / FP 3.2.4

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von wp_xyz »

Erwin hat geschrieben:
wp_xyz hat geschrieben:
Erwin hat geschrieben:Also für mich ist all das sehr verwirrend? Da kann man sich ja auf gar nichts verlassen?

Gemach, gemach. Graphik ist kompliziert, und es dauert einige Zeit bis man die Grundprinzipien inne hat...

Zu kompliziert. Obwohl ich einiges dazu gelesen habe, geht bis jetzt nirgends klar hervor, wie das geht.
Es sei denn das eine damals, wo man die Bilder hin und her kopieren muss in 1-2 Extra Objekte und Speicher. Ist aber eben zu kompliziert.
Einfaches Ausprobieren zwischen I1.Picturre.PNG und I2.Picture.PNG brachte auch keine Sinnvollen Ergebnisse. Auch etwas, was ich nicht nachvollziehen kann.
Deshalb habe ich auch schon überlegt, das Bild einfach auf Canvas zu zeichnen. Aber das dauert dann wieder recht lange.
Wenn man nicht Grafik/Picture mit Canvas vermischen soll, dann sollte man es einem auch einfacher machen, von Grafik/Picture zu Grafik/Picture zu kopieren.
Und die Lektüren schweigen dazu. Das zu Lazarus und FPC sowieso. Da finde ich gerade mal 10 % dessen, was ich Suche, und fast all diese Ergebnisse findet sich aber auch in Büchern zu Delphi. Welche (zu Delphi) sich ebenfalls beim Grafikkopieren eher ausschweigen, als einem was erklären.
Und dann wundern die sich, wenn man alles umsonst haben 'will'. Die meisten Autoren wollen ja selber auch das Geld haben, ohne ordentlich zu liefern.

Etwas runter kopieren/laden? Ungern. Ich sage sogar zu meiner Mutter, und selbst wenn eine Datei von mir kommt, erst Prüfen, weil woher willst Du wissen, ob ich meine Rechner tatsächlich Virenfrei habe?
Aber bleibt mir wohl nichts anderes übrig?

Na gut, wenn du keine Geduld hast, dir alles zu kompliziert ist und zu lange dauert, und wenn dir der Download meiner zip-Datei zu riskant ist, dann kann ich dir nicht helfen.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Mathias »

Ach ja noch: Meiner Meinung nach ist bei PNG die Transparenz über den Alpha-Kanal realisiert, also das 4.Byte in TColor. nicht durch eine "transparente" Farbe.

Normalerweise ist in einer Bitmap das 4. Byte der Alpha-Kanal, aber bei TColor nicht, da wird das 4.Byte zB. für clWindow, etc. gebraucht.

Evtl. kann die Package BGRABitmap das Problem lösen.

Was willst du genau machen, wen du ordentlich Power willst, evtl. OpenGL.


@wp_xyz
Ich wollte den Bildausschnitt probieren. Probiert mit Linux Mint 64Bit

Code: Alles auswählen

Projekt project1 hat Exception-Klasse »External: SIGSEGV« ausgelöst.
 
 In Datei '../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S' in Zeile 38
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von wp_xyz »

Mathias hat geschrieben:@wp_xyz
Ich wollte den Bildausschnitt probieren. Probiert mit Linux Mint 64Bit

Code: Alles auswählen

Projekt project1 hat Exception-Klasse »External: SIGSEGV« ausgelöst.
 
 In Datei '../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S' in Zeile 38

Was für ein Schrott! Mit qt geht's übrigens (zumindest auf 32 bit), und Windows natürlich sowieso.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Mathias »

Was für ein Schrott! Mit qt geht's übrigens (zumindest auf 32 bit), und Windows natürlich sowieso.

Ich habe nichts an den Widget oder ähnlichen rum geschraubt. Es ist das ganz normale Lazarus 1.8.4 .
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von wp_xyz »

Das Lazarus, das auf meiner Mint-VM läuft,verwendet standardmäßig gtk2. Damit sehe ich denselben Fehler wie du. Ich habe dann unter "Projektoptionen" / "Compileroptionen" / "Hinzufügungen und Beeinflussungen" in der Combo "Setze LCLWidgetType" "Wert qt" ausgewählt und das Projekt neu kompiliert, wodurch eine qt-Anwendung entsteht, und dann läufts.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Mathias »

"Wert qt" ausgewählt und das Projekt neu kompiliert, wodurch eine qt-Anwendung entsteht, und dann läufts.

Da muss ich wohl noch was nachinstallieren:

Code: Alles auswählen

/usr/bin/ld: cannot find -lQt5Pas
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Erwin »

wp_xyz hat geschrieben:Na gut, wenn du keine Geduld hast, dir alles zu kompliziert ist und zu lange dauert, und wenn dir der Download meiner zip-Datei zu riskant ist, dann kann ich dir nicht helfen.

Kann mich nicht entsinnen, einen Download grundsätzlich abgelehnt zu haben. Aber ich habe das nicht auf mein Haupt-BS gemacht, sondern unter Win7. Das ist vom Virenscanner eh schon Teils geschrottet. [Sarkasmus] Ein hoch auf die Virenscanner. [/Sarkasmus]
Und was Geduld betrifft: Je öfter man ständig etwas auf das Problem bezogen ausprobiert, was dann doch nicht funktioniert, desto mehr verliere ich zumindest die Lust daran. Irgendwann kommt man sich auch ungewollt ein wenig verarscht vor.

Ich habe mir jetzt den Großteil von der Hand kopiert. Falls ich mich nicht vertan habe, dann laute ein Codeschnippsel:

Code: Alles auswählen

 
OffsetRect(Rdest,Image1.Picture.BitMap.Canvas,Rsrc);
 

Dort jammert bei mir dann der Compiler. Als ich mir OffsetRect genauer angesehen habe, stellte ich fest, dass er nur Rect und zwei weitere LongInts erwartet.
Wie gesagt: Falls ich mich nicht verschrieben habe. Werde deshalb morgen noch mal im anderen BS nachsehen.
Aber auch sonst scheint mir das Ganze nicht wirklich zielführend zu sein, unter anderem weil meine Bilder PNG-Format haben, und nicht BitMap..

wp_xyz hat geschrieben:Das Lazarus, das auf meiner Mint-VM läuft,verwendet standardmäßig gtk2. Damit sehe ich denselben Fehler wie du. Ich habe dann unter "Projektoptionen" / "Compileroptionen" / "Hinzufügungen und Beeinflussungen" in der Combo "Setze LCLWidgetType" "Wert qt" ausgewählt und das Projekt neu kompiliert, wodurch eine qt-Anwendung entsteht, und dann läufts.

Also das sind Dinge, womit ich mich gar nicht beschäftigen will. Wieso soll es nicht die Anwendung sein, die Lazarus auf Grund seiner Installation ausgewählt hat? Würde dann das Programm überhaupt bei anderen Linux-Distri noch laufen?

Wenn die Verzögerung/Auslassen mancher Befehle beim ersten Aufruf an dem Kopieren der Grafik liegt, und das sind ja nicht die einzigen Probleme damit, so muss es doch eine ganz Einfache Lösung mit 2-3 Codezeilen geben?
Lazarus 2.2.0 / FP 3.2.4

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Mathias »

Setze LCLWidgetType

Ich code schon mehrere Jahr mit Lazarus, aber dies musste ich nie verstellen, ausser um mal was zu test.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Erwin »

Das mit "OffsetRect(Rsrc, -Image1.Left, -Image1.Top); " war mein Fehler.
Habe mich beim Abschreiben um eine Zeile vertan, und aus 2 Zeilen 1 gemacht, und somit zu viele Daten im OffsetRect rein geschrieben.
Das Beispielprogramm konnte ich unter Windows nicht zum laufen bringen. Er jammert was davon, dass es Probleme mit 'Scaled' hat.
Jetzt habe ich deshalb auch keine Vorstellung, was genau das bewirkt.
Bei meinem eigentlichem Programm, wo ich alles so weit wie möglich angepasst habe, rührt sich da gar nichts.
Vermute mal, es liegt an den falschen Daten (meinen eigenen Daten) von OffsetRect. Anstatt -Imge1.Left und Top habe ich zuerst '0,0' eingetragen. Dann habe ich es mit den Daten von der Quellimage versucht, also -Quellimage.Left und -Quellimage.Top. Auch da tat sich dann nichts.
Im Buch zu Lazarus und FreePascal steht auch nichts zu dem Befehl OffsetRect, wie üblich halt. Über 90 % zu dem was ich suchte, steht nichts in den teuren Büchern.

Ich habe es inzwischen geschafft, das Quelle-Image auf ein anderes Zwischen-Image zu kopieren, und eine bestimmte Farbe Transparent zu machen. Aber wenn bei einer Wiederholung des Vorgangs nicht vorher Transparent ausschalte, um nach dem Kopieren einzuschalten, ist es nicht mehr transparent?

Dann dachte ich mir, jetzt wo das klappt, kann ich gleich von der Quelle-Image den gewünschten Teil raus kopieren, und in Ziel-Image-1 kopieren. Ja von wegen. Weil dann verschwindet das Image?

Das ergibt doch keinen Sinn? Wenn es mit Zwischen-Image klappt, müsste es doch auch mit Ziel-Image-1 auch klappen. Dass beim Zwischen-Image da Ganze Image-Quelle kopiert wurde, und beim Ziel-Image-1 nur ein Teil kopiert wird, dürfte doch da keinen Unterschied ausmachen? Es ist in meinen Fall auch ein Pixel zu Pixel kopiererei, da das andere ja nicht so recht klappen will?

Inzwischen bin ich aber einen Teil weiter gekommen, in dem ich mich wieder an die Ursprüngliche Kopierversuche erinnerte, und die neue gewonnene Erkenntnis mit dem Auslesen von Transparent etc. kombinierte:

Code: Alles auswählen

 
TransparenteFarbeAuslesen:=QuelleImage.Picture.PNG.Canvas.Pixels[0,0];
ZielImage.Transparent:=False;
ZielImage.Canvas.CopyRect(Rect(0,0,32,32), QuelleImage.Picture.PNG.Canvas, Rect(0,0,32,32));
ZielImage.Picture.PNG.TransparentColor:=TransparenteFarbeAuslesen;
ZielImage.Transparent:=True;
 

Dies scheint so dann doch endlich zu klappen.
Leider kann ich scheinbar eine ZielImage nicht erneut übermalen.
Bin also leider immer noch nicht fertig.

Und bevor da wieder Jemand deshalb Magenkrämpfe bekommt, weil ich von Picture-Canvas auf Image-Canvas kopiere, so soll man mir doch bitte einen anderen und zugleich einfachen Weg zeigen, bzw. Erklären. Weil mit OffsetRect komme ich ohne Erklärung dazu, was genau die letzten 2 Variablen bewirken (Left,Top), damit nicht klar. Und der Testlauf klappte ja (deshalb?) auch nicht. Und bitte, wenn schon andere Lösung, dann doch ohne langwieriges hin und her kopieren über (mehre) TBitmap's. Weil so was kann ja wohl auch nicht das Gelbe vom Ei sein, finde ich.

Edit: Gefunden:

Code: Alles auswählen

 
ZielImage.Picture:=nil;
 

Damit kann ich die Grafik löschen, und somit dann neu bemalen bzw. bekopieren.
Bleibt nur noch zu hoffen, dass es auch wirklich dann Reibungslos funzt, und nicht einer der ZielImage dann beim Härtetest verschwindet etc..
Lazarus 2.2.0 / FP 3.2.4

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von wp_xyz »

Erwin hat geschrieben:Aber auch sonst scheint mir das Ganze nicht wirklich zielführend zu sein, unter anderem weil meine Bilder PNG-Format haben, und nicht BitMap..

Das Ausgangsbild im TImage ist aber ein transparentes PNG; die im Code vorkommende TBitmap ist nur eine Zwischenstufe.

Erwin hat geschrieben:Das Beispielprogramm konnte ich unter Windows nicht zum laufen bringen. Er jammert was davon, dass es Probleme mit 'Scaled' hat.

Streiche die Zeile raus; die kam rein, weil ich standardmäßig mit Laz-trunk arbeite. Alle Lazarus-Versionen ab 1.8.0 kommen damit klar (dein Laz 1.6, lt Signatur, ist nicht mehr aktuell)
Zuletzt geändert von wp_xyz am Do 28. Jun 2018, 11:32, insgesamt 2-mal geändert.

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von MacWomble »

@Erwin
... sinnvoll wäre, den Betreff der ersten Nachricht zu ändern. Mit Button hat das nichts zu tun. Wie wäre Problem mit Canvas und Image?
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: Code von ButotnClick geht beim 1.mal nur zum Teil?

Beitrag von Erwin »

wp_xyz hat geschrieben:Das Ausgangsbild im TImage ist aber ein transparentes PNG; die im Code vorkommende TBitmap ist nur eine Zwischenstufe.

Was er leider beim kopieren ignoriert, also den Alphakanal. Er erkennt diesen einfach nicht bei so einem Vorgang. Ansonsten könnte ich mir nämlich die Auswahl einer Transparenten Farbe mir sparen, was ich eigentlich vorhatte.

MacWomble hat geschrieben:@Erwin
... sinnvoll wäre, den Betreff der ersten Nachricht zu ändern. Mit Button hat das nichts zu tun. Wie wäre Problem mit Canvas und Image?

Habe es geändert. Sinnvoll fände ich es auch, wenn man etwas mehr in die Überschrift schreiben können. Weil ein komplexes Problem mit paar Wörtern zu umschreiben ... .
Lazarus 2.2.0 / FP 3.2.4

Antworten