AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

PNG zur Laufzeit in ImageList einfügen

Ein Thema von bezarre · begonnen am 1. Mai 2010 · letzter Beitrag vom 12. Feb 2011
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.400 Beiträge
 
Delphi 12 Athens
 
#1

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 10. Feb 2011, 17:18
Sicher daß TBitmap Transparenz kann?

Ich dachte das hätte im 32-Bit-Modus RGBP und nicht RGBA?
(Red, Green, Blue, Palette/Alpha)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#2

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 10. Feb 2011, 17:36
Ja, TBitmap unterstütz den Alpha-Kanal.
Ich hatte das vor einigen Tage getestet, als ich eigene Marker-Icons für Google Maps erstellen wollte.
Transparente_Marker.jpg
Gezeichnet wird dabei in ein TPNGImage, was für sich genommen noch nichts besonderes ist. Erst bei der Erstellung des Schattenbildes wird es interessant:
Dabei wird das PNG-Bild als Maske samt Transparenz in ein Bitmap kopiert, perspektivisch verzerrt, gefiltert und wieder zurück in ein (neues) PNG-Image kopiert - und das alles unter Beibehaltung der Transparenz.
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.400 Beiträge
 
Delphi 12 Athens
 
#3

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 10. Feb 2011, 20:23
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 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".
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (10. Feb 2011 um 20:25 Uhr)
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#4

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 11. Feb 2011, 11:21
Es geht

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. 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
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#5

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 11. Feb 2011, 15:49
Sind hier nur Skeptiker unterwegs!?
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:
Transparenz.jpg

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...
Angehängte Dateien
Dateityp: zip Transparenz.zip (854,2 KB, 39x aufgerufen)
Thomas Nitzschke
Google Maps mit Delphi

Geändert von Thom (11. Feb 2011 um 15:59 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 11. Feb 2011, 16:37
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..
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#7

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 11. Feb 2011, 17:32
Etwas OT:
Ich bin nicht gläubig.
Ich auch nicht... Deshalb finde ich Matthias Eissing's Berufsbezeichnung auch immer etwas befremdlich, wenn ich wieder einmal darüber stolpere: National Evangelist Germany. 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...

Mal sehen, was himitsu dazu meint... (Damit meine ich nicht die Glaubensfrage sondern die Transparenzfähigkeit von Bitmaps.)
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#8

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 10. Feb 2011, 17:38
Also ich hab folgendes probiert, aber geht noch nicht:

Delphi-Quellcode:
      Image := TPngImage.Create;
      Image.Transparent := true;
      Image := GetPNG('ABC');

      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 := clBlack;

          Image2.Canvas.TextOut(16 - Image.Canvas.TextWidth(Text), - 2, Text); // HIER schreibe ich den Text ins Image2

          for y := 0 to Image2.Height - 1 do
          begin
            for x := 0 to Image2.Width - 1 do
            begin
              // HIER wird der Text ins Image "kopiert"
              if Image2.Canvas.Pixels[x, y] = clBlack then
                Image.Pixels[x, y] := clBlack;
            end;
          end;
        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);

            // HIER soll der Text im Image nicht überschrieben werden
            if Pixels[x, y] <> clBlack then
              Pixels[x, y] := ColorHLSToRGB(NewHue, Trunc((pb^[x] + NewLuminance) / 2), NewSaturation);
          end;
        end;
      end;
Lieder sehe ich noch keinen Text. Wenn ich TextOut dierekt auf Image mache, sehe ich nur dort Text wo im Ursprungsimage keine Transparenz vorhanden ist.

P.S.: ach so mit ColorHLSToRGB(NewHue, Trunc((pb^[x] + NewLuminance) / 2), NewSaturation); wird das PNG (hat nur den Alphachannel) in der "neuen" Farbe eingefärbt.

Geändert von David Martens (10. Feb 2011 um 17:41 Uhr)
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#9

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 10. Feb 2011, 17:39
@Thom: und das Ganze funktioniert auch noch mit TImageList?
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#10

AW: PNG zur Laufzeit in ImageList einfügen

  Alt 10. Feb 2011, 17:46
Zitat:
EWeiss: sorry, aber eine weitere DLL an alle Benutzer ausliefern wollte ich dann doch nicht.
He?
Was für eine DLL?
GDI+ ist auf allen Systemen enthalten.

Zitat:
Weshalb also die ganzen Kopfstände mit GDI+, TPngImageList und Co.?
Weil GDI+ und das ist Fakt einfach das beste ist wenn es um PNG Dateien geht.
Zumindest meine Erfahrung.

gruss

Geändert von EWeiss (10. Feb 2011 um 18:19 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz