Bitmap.Canvas reagiert nicht auf Farbänderung

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
polytlas
Beiträge: 3
Registriert: Mi 22. Mai 2019, 23:38

Bitmap.Canvas reagiert nicht auf Farbänderung

Beitrag von polytlas »

Liebes Forum, ich habe eine TForm mit einem TIMage, in das ich zur Designtime ein Bild (PNG) lade. Nun möchte ich das Bild in meinem Programm verändern. Das funktioniert, nur erscheint die in meinem Beispiel gemalte Ellipse nicht in der gewünschten Farbe:

Code: Alles auswählen

procedure showResult;
var myForm : TForm3;
  
Begin
  myForm:=TForm3.Create(nil);
  myForm.Image1.Picture.Bitmap.Canvas.pen.Style:=psSolid;
  myForm.Image1.Picture.Bitmap.Canvas.pen.Color:=clRed;
  myForm.Image1.Picture.Bitmap.Canvas.Brush.Style:=bsSolid;
  myForm.Image1.Picture.Bitmap.Canvas.Brush.Color:=clRed;
  myForm.Image1.Picture.Bitmap.Canvas.Ellipse(100,100,300,300);
  myForm.ShowModal;
  myForm.Free;
end;  
Wenn die Prozedur aufgerufen wird, erscheint das Bild mit der Ellipse, jedoch in grau, nicht in rot. Meine Suche im Forum hat viele Fragen zur Farbwahl gebracht, aber keine Lösung für das spezielle Problem. Kann mir jemand sagen, was ich falsch mache?
Ich nutze Lazarus 2.2.0 unter Windows 11 (64 Bit).
Vielen Dank!
Thomas

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Bitmap.Canvas reagiert nicht auf Farbänderung

Beitrag von Winni »

hi!

An deinem code ist mehreres unverständlich.

Wenn Du Form und Image sowie die PNG zur Designtime festgelegt hast, wieso wird dann die Form neue created?

Zweitens muss direkt auf den Image1.canvas gezeichnet werden. Der reicht das dann weiter an die Bitmap (oder PNG oder JPG oder ...) um das Zeichnen persistent zu machen. Wenn Du eine PNG lädst und dann auf die Bitmap zeichnest, musst Du Dich nicht über Wundersamkeiten beschweren.
Zeichne also auf Image1.Canvas.

Winni

polytlas
Beiträge: 3
Registriert: Mi 22. Mai 2019, 23:38

Re: Bitmap.Canvas reagiert nicht auf Farbänderung

Beitrag von polytlas »

Vielen Dank!
Die Form wird neu kreiert, weil sie beim Start nicht sichtbar sein und nur in bestimmten Situationen gezeigt werden soll. Der Typ TForm3 ist in Lazarus angelegt, aber erst zur Laufzeit wird eine Variable instantiiert. Ich dachte, das sei für ein Dialogfenster so in Ordnung?
Jeweils zur Laufzeit soll das zur Designtime voreingestellte Bild dann spezifisch übermalt werden. Wenn ich direkt auf image1.canvas male, sieht man die Ellipse überhaupt nicht. Kann es sein, dass das setzen des Picture zur Designtime den Canvas des TImage irgendwie sperrt?
Vielen Dank nochmal!

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Bitmap.Canvas reagiert nicht auf Farbänderung

Beitrag von Winni »

Hi!

Da musst Du dich erstmal mit den internen Abläufen von Lazarus beschäftigen.

Und mal Deinen Code betrachten.

Die TForm3 wird automatisch angelegt, die Variable Form3 wird automatisch angelegt und in der .lpr Datei automatisch erzeugt. An diesem Verhalten sollte man als Newbie auch nicht rumbasteln.

Form anzeigen und verstecken geht mit show bzw. showmodal und hide.

Das Malen in Deinem Image sollte in Form1create passieren.

Winni

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Bitmap.Canvas reagiert nicht auf Farbänderung

Beitrag von Winni »

HI!

Ich hab Dir mal ne kleine Demo gemacht - 2 Formen und eine Ellipse aufs Bild

Hoffe, es hilft Dir.

Winni
Dateianhänge
FormDemo.zip
(432.03 KiB) 89-mal heruntergeladen

polytlas
Beiträge: 3
Registriert: Mi 22. Mai 2019, 23:38

Re: Bitmap.Canvas reagiert nicht auf Farbänderung

Beitrag von polytlas »

Vielen Dank!
Das Demo hat geholfen: Während Malen in der FormCreate denselben Effekt hatte, wie im Ausgangsbeispiel, funktioniert es, wenn man die Methode Image1Paint benutzt. Wie ich jetzt sehe, ergibt sich das aus der Dokumentation unter
https://wiki.lazarus.freepascal.org/Dev ... o_a_TImage
"The canvas of the visual area of a TImage is only accessible during Image1.OnPaint via Image1.Canvas."
Die beiden Aufrufe von Image1.invalidate habe ich aus dem Beispielcode herausgenommen. Mit den Aufrufen war es so, dass die Form nicht verschwand, wenn sie geschlossen wurde. Da dass OnPaint-Event ausgelöst wird, wenn das TImage invalidiert wird, schien es mir auch nicht nötig, innerhalb der ImagePaint-Methode Image.invalidate aufzurufen - oder sehe ich da ewas falsch?
Mein - wie erwartet funktionierender - Code sieht jetzt jedenfalls so aus:

Code: Alles auswählen

rocedure TForm3.Image1Paint(Sender: TObject);
begin
  //Image1.invalidate; auskommentiert, vgl. o.
  Image1.Canvas.pen.Style:=psSolid;
  Image1.Canvas.pen.Color:=clRed;
  Image1.Canvas.Brush.Style:=bsSolid;
  Image1.Canvas.Brush.Color:=clRed;
  Image1.Canvas.Ellipse(100,100,300,300);
  //Image1.invalidate;
end;     
Nochmal vielen Dank!

PS: Die dynamische Generierung der Form innerhalb der Prozedur ShowResult habe ich erstmal beibehalten. Die automatische Erzeugung einer Instanz in der .lpr und die Deklarierung einer Variablen Form3 in der zugehörigen Unit hae ich natürlich abgeschaltet/gelöscht.

Antworten