2 Images übereinander, fehlende Transparenz des oberen Image

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

2 Images übereinander, fehlende Transparenz des oberen Image

Beitrag von klausi1305 »

Hallo

ich will 2 Images übereinander legen,
das "untere" Image bildet den Hintergrund, das "obere" den Vordergrund, welches ich als "Paintbox" mißbrauchen will.
Der Hintergedanke, dass mir ne Art .Clear Funktion bei der Paintbox fehlt und ich deshalb ein 2. Image zum zeichnen drüberlegen will.
Auf dem oberen Image sollen zur Laufzeit Linien und Bilder gezeichnet werden.

Wie bekomme ich es hin, dass auf das obere Image gezeichnet wird und ich dieses samt Hintergrund sehe?

Image2.Transparent:=True; bringt nicht wirklich was??

Das onpaint Event wäre das interessante für mich?!

Code: Alles auswählen

procedure TForm1.Image2Click(Sender: TObject);
begin
  showmessage('Test'); //Funktioniert
  //Ab jetzt schwarzes Bidl
  //Image1 Hintergrund Picture wurde über Objektinspektor geladen
  image2.Transparent:=true; //Interessiert keinen
  image2.Canvas.Pen.Color:=clred;
  image2.Canvas.Line(100,100,200,200);
end;
 
procedure TForm1.Image2Paint(Sender: TObject);
begin
  {Es passiert garnichts, ausser das der Hintergrund gezeigt wird}
  //Image1 Picture wurde über Objektinspektor geladen
  image2.Transparent:=true; //Interessiert keinen
  image2.Canvas.Pen.Color:=clred;
  image2.Canvas.Line(100,100,200,200);
end;

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von Michl »

Siehe Diskussion: http://www.delphipraxis.net/104372-%5Bt ... nente.html

Um die Transparenz zu demonstrieren, könntest du 1 Button und 2 Images auf deiner Form plazieren (übereinander), das erste (Image 1) ein Bild hineinladen (beide Images nicht transparent), dann:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var
  i:integer;
begin
  Caption:='Bitte auf das Bild klicken!';
  DoubleBuffered := true;
 
  Image2.Canvas.Brush.Color:=$FF0000;                       //Hintergrundfarbe, die Transparent erscheinen soll
  Image2.Canvas.FillRect(0,0,Image2.Width,Image2.Height);   //mit transparenter Farbe Hintergrund füllen
  Image2.Picture.Bitmap.TransparentColor:=$FF0000;          //setzen der transparenten Farbe
  Image2.Picture.Bitmap.TransparentMode:=tmFixed;           //Modus
  Image2.Transparent:=true;                                 //transparent stellen
end;
 
procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton;    //Zeichnet ein zufällig großes Rechteck
  Shift: TShiftState; X, Y: Integer);
var
  Stream:TMemoryStream;
  i:integer;
begin
  Image2.Canvas.Brush.Color:=random($FFFFFF+1);
  Image2.Canvas.Pen.Color:=0;
  i:=random(50);
  Image2.Canvas.Ellipse(x-i,y-i,x+i,y+i);
 
//  Image2.Picture.SaveToFile('Image2.bmp','bmp');
//  Image2.Picture.LoadFromFile('Image2.bmp');
 
  Stream:=TMemoryStream.Create;                             //Weiss jetzt gerade keinen anderen Weg Canvas aufs Bitmap zu vereinigen???
  Image2.Picture.SaveToStream(Stream);
  Stream.Position:=0;
  Image2.Picture.LoadFromStream(Stream);
  Stream.Free;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Image2.Transparent:=not Image2.Transparent;               //Zeigt Transparenz an/aus
end;                   
Ich denke, dass dieses Vorgehen für deine Zwecke nicht zielführend ist (wollte dir nur die Transparenz zeigen) , besser ist es eine Paintbox zu nutzen siehe Link!

Wer´s brauch und nicht tippen will noch als zip:
Dateianhänge
Transparent.ZIP
(300.21 KiB) 99-mal heruntergeladen
Zuletzt geändert von Michl am Mi 24. Jul 2013, 23:22, insgesamt 2-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von klausi1305 »

Riesen Dank,

das erfüllt vollkommen meine Ansprüche!!

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von klausi1305 »

ne frage hätte ich noch :D

wie kann ich das obere Image (das Transparente) komplett oder auch nur teilweise clearen, wenn man vorher par Canvas Geschichten auf diesem getrieben hat?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von Michl »

So wie du´s erstellt hast:

Code: Alles auswählen

  Image2.Canvas.Brush.Color:=$FF0000;                       //Hintergrundfarbe, die Transparent erscheinen soll
  Image2.Canvas.FillRect(0,0,Image2.Width,Image2.Height);   //mit transparenter Farbe Hintergrund füllen
Komplette Canvasfläche mit transparenter Farbe füllen!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von klausi1305 »

Wenn ich folgendes anwende, bleiben trotzdem die Linien dich gezeichnet habe sichtbar, halt in ner anderen Farbe

Code: Alles auswählen

MyVordergrund.Canvas.Clear; //KEINE AUSWIRKUNG 
  MyVordergrund.Canvas.Brush.Color:=$FF0000;                       //Hintergrundfarbe, die Transparent erscheinen soll
  MyVordergrund.Canvas.FillRect(0,0,MyVordergrund.Width,MyVordergrund.Height);   //mit transparenter Farbe Hintergrund füllen  
Die einzige Lösung die mir bisher kam, war das ich alles lösche und neu erstelle wie hier http://www.lazarusforum.de/viewtopic.ph ... 067#p63131
sprich erst Objekt free und dann wieder create

bloss das erscheint mir bissel doof...

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von Michl »

Das ist das gleiche Problem, was ich schon mal schrieb. Ein TImage ist für dieses Vorhaben, wie du es willst, eigentlich nicht gedacht. Es gibt beim TImage eine Bitmap und eine Canvas. Auf der Canvas finden alle Zeichenoperationen statt. Lies dir das mal durch: http://wiki.freepascal.org/Developing_w ... ein_TImage, da ist das besser erklärt, als ich das kann.

Ein Workarround würde wieder das darstellen:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
var
  Stream:TMemoryStream;
begin
  Image2.Canvas.Brush.Color:=$FF0000;                       //Hintergrundfarbe, die Transparent erscheinen soll
  Image2.Canvas.FillRect(0,0,Image2.Width,Image2.Height);   //mit transparenter Farbe Hintergrund füllen
 
  Stream:=TMemoryStream.Create;                            
  Image2.Picture.SaveToStream(Stream);
  Stream.Position:=0;
  Image2.Picture.LoadFromStream(Stream);
  Stream.Free;
end;  

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von klausi1305 »

Bis zu dem Punkt transparente Farbe setzen und Fillrect komme ich mit...

kannst du mir den "geistigen" Hintergrund mit dem speichern erklären...(code kopieren ist doof, verstehen hilft mir mehr)
Was nen Stream ist und das was ich und wende mittlerweile an!!!

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von Michl »

klausi1305 hat geschrieben:Was nen Stream ist
siehe http://wiki.freepascal.org/Streaming_components/de

Ich habe jetzt nur das Speichern in den Stream/Datenstrom/Speicher und nicht auf die Festplatte genommen, weil es um das x-fache schneller geht. Das macht für das Beispiel aber nicht den großen Unterschied.

Ich wollte dir eigentlich nur zeigen, was transparent true/false bewirkt. Da Canvas keine Transparenz zur Verfügung stellt sondern nur das Bitmap vom Image, musste das Canvas zuvor auf das Bitmap gerastert werden. Dazu ist mir jetzt kein besserer Weg eingefallen, als das über Speichern (da wird das Canvas und das Bitmap zu einem tatsächlichen Pixel-Bild zusammengeführt) und wieder Laden (das Canvas ist dann wieder clean, im Image liegt nur noch das Bitmap vor).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von Michl »

Bevor ich Geschimpftes bekomme :wink: - zwischenzeitliche Speichernutzungen sollen in einen try except block:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);             //Vordergrundimage komplett transparent machen
var
  Stream:TMemoryStream;
begin
  Image2.Canvas.Brush.Color:=$FF0000;                       //Hintergrundfarbe, die Transparent erscheinen soll
  Image2.Canvas.FillRect(Image2.Canvas.ClipRect);           //mit transparenter Farbe Hintergrund füllen
 
  Stream:=TMemoryStream.Create;
  try
    Image2.Picture.SaveToStream(Stream);
    Stream.Position:=0;
    Image2.Picture.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von klausi1305 »

Servus,

Ich habe jetzt die einzelnen Objekte in der Klasse "gekapselt" (ich hoffe der Ausdruck ist ok)
Ich kann 1 mal denn Vordergrund (Gitternetz) createn. Anschliessend versuche ich ihn zu löschen mit Free....
wenn ich den Vordergrund (Gitternetz) erneut createn will, bekomm ich nen SigsEGV...!!! :shock:
Mein gefährliches Halbwissen sagte mit doch, das mit dem Free oder Destroy ist das Ding vollkommen weg ist?!

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2815
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von m.fuchs »

Zeig doch mal ein bisschen Code.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von klausi1305 »

Code: Alles auswählen

procedure TSpielfeld.GitternetzZeigen;
Var
  Zaehler1, Zaehler2 : Integer;
Begin
  //Vordergrund erzeugen
         //Hier fliegts beim 2. Mal raus
         MyGitternetz :=TImage.Create(MyGitternetz);//Gitternetz Image  über Hintergrund in der Scrollbox erzeugen
         //------------------------------------------
         MyGitternetz.Parent:= MyScrollbox;
         MyGitternetz.Top:=0;
         MyGitternetz.Left:=0;
    //Größe Vordergrund an Hintergrund anpassen
         MyGitternetz.Width:=MyHintergrund.Picture.Width;                          //Vordergrund an Hintergrund anpassen
         MyGitternetz.Height:=MyHintergrund.Picture.Height;                        //Vordergrund an Hintergrund anpassen
         MyGitternetz.AutoSize:=true;                                              //  Autosize setzen
    //Transparenz setzen
         MyGitternetz.Canvas.Brush.Color:=$FF0000;                       //Hintergrundfarbe, die Transparent erscheinen soll
         MyGitternetz.Canvas.FillRect(0,0,MyGitternetz.Width,MyGitternetz.Height);   //mit transparenter Farbe Hintergrund füllen
         MyGitternetz.Picture.Bitmap.TransparentColor:=$FF0000;          //setzen der transparenten Farbe
         MyGitternetz.Picture.Bitmap.TransparentMode:=tmFixed;           //Modus
         MyGitternetz.Transparent := True;      // Transparenz an
 
  {-------------Gitter 37x37 auf Vordergrund zeichnen-------------------------}
 
 
             MyGitternetz.Picture.Bitmap.Canvas.Pen.Color:=CLred;        // Linienfarbe des Gitters
 
             //Zeichnen der Gitterlinien von Links nach Rechts
             Zaehler1:=-1;
             Zaehler2:=-37;
             Repeat
               inc(Zaehler1);
               inc(Zaehler2,37);
               MyGitternetz.Picture.Bitmap.Canvas.MoveTo(Zaehler2,0);
               MyGitternetz.Picture.Bitmap.Canvas.lineTo(Zaehler2,MyGitternetz.Height);
             until Zaehler1 = AnzfelderBreite;
 
             //Zeichnen der Gitterlinien von Oben nach Unten
             Zaehler1:=-1;
             Zaehler2:=-37;
             Repeat
               inc(Zaehler1);
               inc(Zaehler2,37);
               MyGitternetz.Picture.Bitmap.Canvas.MoveTo(0,Zaehler2);
               MyGitternetz.Picture.Bitmap.Canvas.lineTo(MyGitternetz.Width,Zaehler2);
             until Zaehler1 = AnzFelderHoehe;
end;
 
procedure TSpielfeld.GitternetzLoeschen;
begin
  MyGitternetz.Free;
end;
 
und im Testprogramm

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
  Feld.GitternetzZeigen;
end;
 
procedure TForm1.Button3Click(Sender: TObject);
begin
  Feld.Gitternetzloeschen;
end;       

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2815
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: 2 Images übereinander, fehlende Transparenz des oberen I

Beitrag von m.fuchs »

Code: Alles auswählen

MyGitternetz :=TImage.Create(MyGitternetz);
Du möchtest dass MyGitternetz sein eigener Owner ist? Das funktioniert nicht. Wenn du es ohne Owner erzeuegn möchtest verwende nil.

Code: Alles auswählen

MyGitternetz :=TImage.Create(nil);
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten