Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Zwei Transparente PNGs kombinieren (https://www.delphipraxis.net/162556-zwei-transparente-pngs-kombinieren.html)

ddcool 29. Aug 2011 11:03


Zwei Transparente PNGs kombinieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo liebe DPler,

ich möchte gerne zwei PNGs, die beide transparente Bereiche enthalten miteinander kombinieren, so dass die Transparenz der beiden Bilder nicht addiert wird. Im Anhang ein Beispiel, welches genau das Problem aufzeigt. Der untere schwarze Kasten und der Verlaufeffekt sind das erste Bild, welches als Hintergrund benutzt wird. der obere Kasten ist das Bild, welches auf den Hintergrund gezeichnet wird.
Dazu benutzte ich folgende Methode:

Code:
  TestImage := TPngImage.Create;
  TestImage.Assign(TPngImage(imgBackground.Picture.Graphic));
  TestImage.Canvas.Draw(20, 30, ImageList.ButtonImage);
  ...
  TPngImage(imgBackground.Picture.Graphic).Assign(TestImage);
(ImageList.ButtonImage ist vom Typ TPngImage und wird zuvor mit einem PNG befüllt)

Eigentlich ist der obere Kasten (ButtonImage) eine gleichbleibend halb transparente schwarze Box, jedoch wird die Transparenz des Hintergrundes addiert, sodass das ButtonImage mit verblasst.

Gibt es eine Möglichkeit das zu verhindern, bzw das ButtonImage auf dem Hintergrund anders zu Zeichnen, sodass die korrekte Transparenz bestehen bleibt?

In diesem Thread wird das ganze ansatzweise besprochen, jedoch möchte ich nicht jeden Pixel umrechnen müssen.

Danke für jede Hilfe!


Lieben Gruß,

ddcool

ddcool 30. Aug 2011 11:47

AW: Zwei Transparente PNGs kombinieren
 
Nach langem Suchen haben ich folgenden Quelltext gefunden, der genau das macht was ich will.

Code:
procedure DrawPngWithAlpha(Src, Dest: TPngImage; const R: TRect);
var
  X, Y: Integer;
  Alpha: PByte;
begin
  Src.Draw(Dest.Canvas, R);

  for Y := R.Top to R.Bottom - 1 do
    for X := R.Left to R.Right - 1 do
    begin
      Alpha := @Dest.AlphaScanline[Y]^[X];
      Alpha^ := Min(255, Alpha^ + Src.AlphaScanline[Y - R.Top]^[X - R.Left]);
    end;
end;
Allerdings ist der Quelltext sehr unperformant, da ich ja sehr häufig die Form neu zeichnen lasse, da ich die gesamte Form mittels UpdateLayeredWindow zeichne.
Gibt es da alternativen, oder ist meine Herangehensweise eventuell falsch?

Ich habe ein TImage-Object auf welches dann aus Bildresourcen die Form zusammengesetzt wird. Das realisiere ich erstmalig mit Assign, um den Hintergrund zuzuweisen und alles weitere kommt dann mit Draw, oder oben genannter Funktion auf das TImage.
Dann benutze ich TJvTransparentForm mit dem TImage als Layer, um meine Form mit dem gewünschten Design auszustatten. Jedoch will ich, dass sich die Form alle paar Millisekunden neu Zeichnet, da sich das TImage ja auch verändern kann (Laufschrift, etc.).

Macht man das so, oder benutzt man da lieber ein OnPaint-Ereignis? Momentan liegt die CPU-Auslastung bei ca 10-15%, was meiner Meinung nach zu viel ist.

himitsu 30. Aug 2011 12:07

AW: Zwei Transparente PNGs kombinieren
 
Zitat:

da sich das TImage ja auch verändern kann
Ständig neu Zeichen, da sich eventuell etwas ändern könnte?
Zeichne doch nur neu, wenn sich wirklich was ändert und womöglich dann auch nur diesen Teil.

TImage ist eigentlich nicht gut geeignet, für schnelle veränderungen, da es recht langsam ist.
Könnte man stattdessen auch etwas Anderes nehmen, zusammen mit einem Offscreenbitmap? (eventuell TPaintBox oder direkt das Canvas der Form)


Ich weiß ja nicht was AlphaScanline so alles macht, aber es wäre bestimmt besser, wenn das nicht für jedes X abgerufen würde ... einmal pro Y reicht doch auch aus.

Delphi-Quellcode:
for Y := R.Top to R.Bottom - 1 do
  DestAlpha := Dest.AlphaScanline[Y];
  SrcAlpha := Src.AlphaScanline[Y - R.Top];
  for X := R.Left to R.Right - 1 do
    DestAlpha[X] := Min(255, DestAlpha[X] + SrcAlpha[X - R.Left]);
end;

ddcool 30. Aug 2011 14:56

AW: Zwei Transparente PNGs kombinieren
 
Danke himitsu,

deine Methode klappt merklich schneller, was ja auch nicht verwunderlich ist.
Problem dabei ist leider nur, wenn ich einen Farbverlauf als Hintergrund habe, der von links nach rechts Transparent wird, greift das ganze nicht mehr so wie es soll...

Gibt es eine alternative Möglichkeit, zwei PNGs mit unterschiedlichen Transparenzen mit einander zu Kombinieren und die Transparenzen so zu verrechnen, dass beide Bilder trotzdem wie original aussehen?

Im Prinzip so als würde ich in Photoshop zwei Ebenen erstellen und jeweils ein PNG auf jede Ebene legen.

Vielen Dank & Gruß

Jens01 30. Aug 2011 15:36

AW: Zwei Transparente PNGs kombinieren
 
Eigentlich müßte sowas mit http://graphics32.org funktionieren.

schlagzu 30. Aug 2011 15:38

AW: Zwei Transparente PNGs kombinieren
 
Ich kann nur graphics32 empfehlen. Mir der kann man alles mit verschiedenen Modi kombinieren, übermalen, drehen etc. Einfach mal in der Doku nachsehen.

schlagzu 30. Aug 2011 15:38

AW: Zwei Transparente PNGs kombinieren
 
verdammt ich war zu langsam

ddcool 31. Aug 2011 09:06

AW: Zwei Transparente PNGs kombinieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vielen Dank für den Tipp :)

Muss ich mich dann mal reinarbeiten, aber andere Frage zu dem ganzen Thema:

Ist es eigentlich noch zeitgemäß diesen Weg zu gehen, um eine Applikation mit seinem individuellen Design auszustatten (sprich eigene PNGs)? Oder ist dafür einfach eine andere Methode empfehlenswert?
Habe mal was von Direct2D oder OpenGL Empfehlungen gelesen, aber die Frage ist, ob man damit auch so schöne halbtransparente Formulare hin bekommt...

Im Anhang das Design, welches ich umsetzen möchte (ohne den Holzhintergrund versteht sich).

Bummi 31. Aug 2011 10:00

AW: Zwei Transparente PNGs kombinieren
 
Ich kann nur GDI+ empfehlen schlank und schnell

Jens01 31. Aug 2011 11:16

AW: Zwei Transparente PNGs kombinieren
 
Zitat:

Habe mal was von Direct2D oder OpenGL Empfehlungen gelesen, aber die Frage ist, ob man damit auch so schöne halbtransparente Formulare hin bekommt...
Das bekommt man mit OpenGL ganz sicher hin. OpenGL ist aber sehr mächtig und man braucht etwas, um sicher dort einzuarbeiten. Je flexibler und größer Deine Grafikaufgaben sind, desto mehr ist OpenGL zu empfehlen http://www.delphigl.com/. Für einfache Sachen würde ich aber Graphics32 mit GR32_lines http://angusj.com/delphi/gr32_lines.php anraten


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:05 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