Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   PNG zur Laufzeit in ImageList einfügen (https://www.delphipraxis.net/150954-png-zur-laufzeit-imagelist-einfuegen.html)

Thom 10. Feb 2011 18:21

AW: PNG zur Laufzeit in ImageList einfügen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von David Martens (Beitrag 1080891)
@Thom: und das Ganze funktioniert auch noch mit TImageList?

Ja. Hier der Beweis:
Anhang 33334
Das rechte obere Smiley ist ein TImage mit dem Original-PNG-Bild. Im FormShow-Event wird dieses Bild in eine normale Image-Liste kopiert (siehe erstes Beispiel). Diese Image-Liste wird vom Button zur Darstellung des Icons genutzt (ohne jeglichen eigenen Quelltext). Das Quadrat unteren ist ein TShape-Objekt, das in seiner rechten oberen Ecke von einer kleinen PaintBox überlagert ist und in die mit
Delphi-Quellcode:
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  ImageList1.Draw(PaintBox1.Canvas,0,0,0);
end;
gezeichnet wird. Mehr ist das nicht: Keine Magie, keine Tricks...
Eine Vergrößerung zeigt, das der Alpha-Kanal wirklich vorhanden ist:
Anhang 33335

Zitat:

Zitat von EWeiss (Beitrag 150954)
GDI+ ist auf allen Systemen enthalten.

Nein. Zum Beispiel auf Windows 98 und Windows 2000 noch nicht.

EWeiss 10. Feb 2011 18:25

AW: PNG zur Laufzeit in ImageList einfügen
 
Ich möchte bezweifeln das der AlphaChannel korrekt angezeigt wird..
Schon mal den AlphaChannel auf 75% Durchsichtigkeit verändert und dann anzeigen lassen ?

es sollte ja dann Transparent über deinen Panel liegen (Durchscheinend)

So in der art .. Siehe Pic
Hintergrundbild mit aufgesetztem PNG AlphaChannel 50%

gruss

Thom 10. Feb 2011 18:49

AW: PNG zur Laufzeit in ImageList einfügen
 
Liste der Anhänge anzeigen (Anzahl: 1)
OK - Hier der Versuch mit Geister-Smileys:
Anhang 33337
Die Transparenz ist gut zu erkennen. Allerdings wird auch sichtbar, daß die Objekte (TImage und TButton) offenbar etwas unterschiedliche Zeichenalgorithmen verwenden, da die Farbsättigung differiert.

P.S.:
@EWeiss: Dein Bild sieht natürlich besser aus! 8-)

EWeiss 10. Feb 2011 18:52

AW: PNG zur Laufzeit in ImageList einfügen
 
Zitat:

Zitat von Thom (Beitrag 1080919)
OK - Hier der Versuch mit Geister-Smileys:
Anhang 33337
Die Transparent ist gut zu erkennen. Allerdings wird auch sichtbar, daß die Objekte (TImage und TButton) offenbar etwas unterschiedliche Zeichenalgorithmen verwenden, da die Farbsättigung differiert.

Supi..
Danke das du mich überzeugen konntest.
Denke damit kann man leben :)

Zitat:

P.S.:
@EWeiss: Dein Bild sieht natürlich besser aus! 8-)
Jo denke auch ;)
hehehehe

gruss

Thom 10. Feb 2011 19:04

AW: PNG zur Laufzeit in ImageList einfügen
 
Zitat:

Zitat von EWeiss (Beitrag 1080921)
Danke das du mich überzeugen konntest.

Keine Ursache - gern geschehen! :thumb:

P.S.:
Dein Bild wird ja immer besser! 8-)
Gefällt mir!

himitsu 10. Feb 2011 20:23

AW: PNG zur Laufzeit in ImageList einfügen
 
Zitat:

Zitat von Thom (Beitrag 1080888)
Ja, TBitmap unterstütz den Alpha-Kanal.

Gut, wenn man es über in ein TBitmap reinquetzt und keine delphieigenen Komponenten/Befehle verwendet, um es anzuzeigen oder zu bearbeiten, dann mag es gehen, wenn man das PalettenByte als Alphakanal mißbraucht und das TBitmap quasi nur als Speichermedium verwendet. Von den "normalen" Delphi/Windows-Funktionen würde der "Alpha"-Kanal aber bestimmt nur als Palette behandelt.


Hab nochmal schnell nachgeguck:
Zitat:

Zitat von OH:TColor
Hat das höchstwertige Byte den Wert Null, erhalten Sie eine Farbe, die derjenigen in der Systempalette am ähnlichsten ist. Ist das höchstwertige Byte Eins ($01 bzw. 0x01), ergibt das eine Farbe, die derjenigen in der aktiven Palette am ähnlichsten ist. Wenn Sie das höchstwertige Byte auf Zwei ($02 bzw. 0x02) setzen, wird der Wert an die ähnlichste Farbe in der logischen Palette des aktuellen Gerätekontexts angepasst.

Und dann noch:
Delphi-Quellcode:
clSystemColor = $FF000000;
clNone = TColor($1FFFFFFF);
clDefault = TColor($20000000);

Genauso kann ich ja Binärdaten in einem (Ansi)String zwischenspeichern und es ist dennoch nicht sofort ein lesbarer/anzeigbarer "Text".

David Martens 11. Feb 2011 11:21

AW: PNG zur Laufzeit in ImageList einfügen
 
Es geht :dp:

So um nur noch mein Ergebnis zu präsentieren:

1. Mit TImageList hat es NICHT geklappt. Was wohl auch an mir liegt. Ich hatte vergessen zu sagen das Bild selbst hat unterschiedliche Transparenz ich will das Bild nicht mit eine Gesamttransparenz zeichnen.

Hier der Code mit dem es geht und unten dann die Erklärung dazu:
Delphi-Quellcode:
      if Image <> nil then
      begin
        if Color <> clNone then
        begin
          Image2 := TPngImage.CreateBlank(COLOR_GRAYSCALE, 1, 16, 16);

          Image2.Canvas.Brush.Style := bsClear;

          Image2.Canvas.Font. Name := 'Small Fonts';
          Image2.Canvas.Font. Size := 5;
          Image2.Canvas.Font. Color := clWhite;

          Image2.Canvas.TextFlags := Image2.Canvas.TextFlags or ETO_OPAQUE;
          Image2.Canvas.TextOut(16 - Image2.Canvas.TextWidth(Text), - 2, Text);
        end;
      end;

      with Image do
      begin
        for y := 0 to Height - 1 do
        begin
          pb := AlphaScanline[y];
          for x := 0 to Width - 1 do
          begin
            ColorRGBToHLS(ImageColor, NewHue, NewLuminance, NewSaturation);

            if Image2.Pixels[x, y] = clWhite then
            begin
              Pixels[x, y] := clBlack;
              pb^[x] := 255;
            end
            else
              Pixels[x, y] := ColorHLSToRGB(NewHue, Trunc((pb^[x] + NewLuminance) / 2), NewSaturation);
          end;
        end;
      end;

      if Image <> nil then
      begin
        Liste.AddPng(Image);
      end;
1.
Delphi-Quellcode:
TPngImage.CreateBlank(COLOR_GRAYSCALE, 1, 16, 16);
erzeugt ein SCHWARZES Bild, ergo muß ich Weiß als Textfarbe nehmen.
2.
Delphi-Quellcode:
            if Image2.Pixels[x, y] = clWhite then
            begin
              Pixels[x, y] := clBlack;
              pb^[x] := 255;
            end
Das ist der eigentliche Knackpunkt, hier muß ich den Alphachannel auch noch setzen.

Vielen Dank an alle
David

Thom 11. Feb 2011 15:49

AW: PNG zur Laufzeit in ImageList einfügen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Sind hier nur Skeptiker unterwegs!? :wink:
Zitat:

Zitat von himitsu (Beitrag 1080944)
Gut, wenn man es über in ein TBitmap reinquetzt und keine delphieigenen Komponenten/Befehle verwendet, um es anzuzeigen oder zu bearbeiten, dann mag es gehen, wenn man das PalettenByte als Alphakanal mißbraucht und das TBitmap quasi nur als Speichermedium verwendet. Von den "normalen" Delphi/Windows-Funktionen würde der "Alpha"-Kanal aber bestimmt nur als Palette behandelt.

Im Bitmap kann die Farbtiefe über die Eigenschaft PixelFormat eingestellt werden. pf1bit erzeugt zum Beispiel ein Schwarz-Weiß-Bild. In einem Byte sind also (Windows-)intern (!!!) 8 nebeneinanderliegende Pixel enthalten. Kannst Du gern über ScanLine überprüfen. Wenn Du da mit der 32-Bit-TColor-Keule draufhauen würdest, würdest du dem Tapferen Schneiderlein Konkurrenz machen und auf einmal sogar 32 Pixel erschlagen! Die Methoden GetPixel und SetPixel des Windows API's (gekapselt in der Eigenschaft Canvas.Pixels[x,y]) rechnen die tatsächlich im Bitmap enthaltenen Werte um. Bei einem Schwarz-Weiß-Bild könnte ich natürlich ohne Fehlermeldung den Wert clRed übergeben - darf mich aber dann natürlich nicht wundern, wenn das nicht im Bitmap ankommt!

Ich habe irgendwie den Eindruck, daß Du nach dem Motto gehts: Was nicht sein darf, das kann nicht sein.
Probier's doch einfach aus: Lade ein beliebiges PNG-Bild in eine TImage-Komponente, kopiere zur Laufzeit das Bild in ein temporäres Bitmap und laß es in einer PaintBox anzeigen. Du wirst sehen: Die Transparenz des PNG-Bildes bleibt erhalten. Und jetzt kommt die (rhetorische) Frage: Wer hat das Bitmap auf den Bildschirm gezaubert? Das war Windows. Also kommt Windows (unter Berücksichtigung einiger Bedingungen) tatsächlich mit Alpha-Werten in Bitmaps zurecht!

Damit Du's und alle anderen, die es nicht glauben (wollen/können) habe ich eine kleine Demo fertig gemacht:
Anhang 33345

Der Kern des Ganzen:
Delphi-Quellcode:
procedure TForm2.PaintBox1Paint(Sender: TObject);
var
  Bmp: TBitmap;
begin
  Bmp:=TBitmap.Create;
  try
    Bmp.Assign(Image1.Picture.Graphic);
    PaintBox1.Canvas.Draw(0,0,Bmp);
  finally
    Bmp.Free;
  end;
end;
Der Alpha-Kanal wird vom PNG-Bild korrekt in das Bitmap übernommen und von Windows wiederum richtig auf den Bildschirm dargestellt.
w.z.b.w.
q.e.d.

Sowohl die PaintBox als auch das Image sind auf dem Hintergrund verschiebbar. Wer's dann immer noch nicht glaubt, dem kann ich auch nicht mehr helfen... :roll:

EWeiss 11. Feb 2011 16:37

AW: PNG zur Laufzeit in ImageList einfügen
 
Zitat:

Wer's dann immer noch nicht glaubt, dem kann ich auch nicht mehr helfen...
Ich bin nicht gläubig.
Aber in dem Fall schon ;)

Dafür muss ich das nicht extra laden..

Thom 11. Feb 2011 17:32

AW: PNG zur Laufzeit in ImageList einfügen
 
Etwas OT:
Zitat:

Zitat von EWeiss (Beitrag 1081095)
Ich bin nicht gläubig.

Ich auch nicht... :lol: Deshalb finde ich Matthias Eissing's Berufsbezeichnung auch immer etwas befremdlich, wenn ich wieder einmal darüber stolpere: National Evangelist Germany. :gruebel: Ich weiß: Das ist wohl eher im Sinne eines Technology Evangelisten gemeint - aber trotzdem hat es für mich einen merkwürdigen Beigeschmack. Tja, ja - die Ammis (Embarcadero) mit ihrem Sendungsbewußtsein...8-)

Mal sehen, was himitsu dazu meint... (Damit meine ich nicht die Glaubensfrage sondern die Transparenzfähigkeit von Bitmaps.) :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:08 Uhr.
Seite 3 von 4     123 4      

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