AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

PNG in TImage falsch dargestellt

Ein Thema von tumo · begonnen am 14. Apr 2020 · letzter Beitrag vom 29. Apr 2020
Antwort Antwort
Seite 5 von 6   « Erste     345 6   
venice2
(Gast)

n/a Beiträge
 
#41

AW: PNG in TImage falsch dargestellt

  Alt 24. Apr 2020, 18:28
Ich habe jetzt nicht alles gelesen..
Aber was für eine Qualität bzw. Ansicht erwartest du bei einem Indizierten *.png!
Das kann nur inkorrekt dargestellt werden.

Ändere es doch einfach mal von 8 auf 32Bit.
Ich behaupte jetzt einfach mal das TImage mit indizierten *.png's nicht klar kommt.

Geändert von venice2 (24. Apr 2020 um 18:34 Uhr)
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.010 Beiträge
 
Delphi 2009 Professional
 
#42

AW: PNG in TImage falsch dargestellt

  Alt 25. Apr 2020, 12:24
Ich habe jetzt nicht alles gelesen..
Aber was für eine Qualität bzw. Ansicht erwartest du bei einem Indizierten *.png!
Das kann nur inkorrekt dargestellt werden.
Nein.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
tumo

Registriert seit: 28. Apr 2014
46 Beiträge
 
Delphi 10.3 Rio
 
#43

AW: PNG in TImage falsch dargestellt

  Alt 25. Apr 2020, 17:10
@Medium
Ich wüsste jetzt nicht, wo man den Vergrößerungs-Algorithmus einstellen kann. Tatsächlich macht er das schon mit NearestNeighbour (oder etwas, was verdammt danach aussieht), was auch das ist, was ich will. Verfolgt man die Draw()-Methode von PNGImage landet man mit BitTransparency früher oder später in einer Prozedur mit dem schönen Namen "DrawTransparentBitmap". Da drin wird mit Windows-Blt-Befehlen weiter gearbeitet. Ab da verstehe ich nicht mehr wirklich viel :/.

@venice2
Ich erwarte, dass die Pixeldaten korrekt dargestellt werden, auch in vergrösserter Version. Es gibt noch einen Unterschied zwischen hässlich und inkorrekt darstellen. Es "einfach" mal von 8bit auf 32bit zu ändern (1.) geht mit Palettenbildern nicht, (2.) lässt TPNGImage á la BitDepth=32bit nicht zu, (3.) ist in meinem Fall nicht möglich, da die Bilder so gegeben sind. Die Behauptung ist zwar ganz nett, aber eben nicht richtig bzw. offensichtlich. TPNGImage hat einen extra Case für BitTransparency (die nur in Palettenbildern vorkommt) in der Draw()-Methode. Andere, nicht-transparente, indizierte PNGs kann es ja problemlos.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#44

AW: PNG in TImage falsch dargestellt

  Alt 25. Apr 2020, 19:50
Zitat:
aber eben nicht richtig bzw. offensichtlich. TPNGImage hat
Ihr solltet euch mal langsam einigen.
Was denn nu TImage oder TPNGImage

Zitat:
(1.) geht mit Palettenbildern nicht
geht nicht gibt es nicht.

Es ist ein einfaches dein Paletten Bild im Speicher zu einem vollwertigen 32Bit PNG Image zu konvertieren.
Was hindert dich daran.
Zitat:
(2.) lässt TPNGImage á la BitDepth=32bit nicht zu
Wofür braucht man die Komponente wenn ich das im Speicher erledigen kann.
Es scheint mir ohne Komponente seid ihr alle aufgeschmissen.
Zitat:
Ab da verstehe ich nicht mehr wirklich viel :/.
Bestätigt meine vermutung.
Zitat:
(3.) ist in meinem Fall nicht möglich, da die Bilder so gegeben sind.
Nichts ist gegeben hinzunehmen. Siehe beide Kommentare zuvor.

Geändert von venice2 (25. Apr 2020 um 22:18 Uhr)
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.010 Beiträge
 
Delphi 2009 Professional
 
#45

AW: PNG in TImage falsch dargestellt

  Alt 26. Apr 2020, 10:24
Zitat:
aber eben nicht richtig bzw. offensichtlich. TPNGImage hat
Ihr solltet euch mal langsam einigen.
Was denn nu TImage oder TPNGImage
Wofür braucht man die Komponente wenn ich das im Speicher erledigen kann.
Es scheint mir ohne Komponente seid ihr alle aufgeschmissen.
So große Töne spucken, wenn man noch nicht mal weiß, was Delphi-Referenz durchsuchenTPNGImage ist...

Zitat:
(1.) geht mit Palettenbildern nicht
geht nicht gibt es nicht.
Du suchst eine Herausforderung? Alles klar, dann erstell doch einfach mal ein Computerprogramm, das irgendein Problem aus dieser Liste in polynomieller Zeit löst.

Es ist ein einfaches dein Paletten Bild im Speicher zu einem vollwertigen 32Bit PNG Image zu konvertieren.
Das ist dennoch ein richtiger Ansatz.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
tumo

Registriert seit: 28. Apr 2014
46 Beiträge
 
Delphi 10.3 Rio
 
#46

AW: PNG in TImage falsch dargestellt

  Alt 26. Apr 2020, 15:46
Das ist dennoch ein richtiger Ansatz.
Gibt es da irgend einen Trick? Mein Ansatz wäre jetzt das pixelweise Parsen in ein neues TPNGObject, bin mir aber nicht sicher, ob das nicht noch effizienter geht.

Das umgeht dann ja aber nur das Problem. Mit anderen Worten, ich muss einen Edgecase für ebendiese Problembilder machen. Naja, ich schätze mal, das ist der sinnvollste Weg für mich, manchmal kann man eben nicht alles haben.
Wäre das ein Bug, den man so bei Embarcadero einreichen müsste? Hab bisher nichts dazu gefunden, kann also gut sein, dass ich der erste bin, der auf diesen Fehler stößt (was mich aber auch wundern würde).

Danke trotzdem für die bisherige Hilfe.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#47

AW: PNG in TImage falsch dargestellt

  Alt 26. Apr 2020, 17:01
Nur damit du siehst das es geht von wegen (So große Töne spucken)
ABer da du Herrn Redeemer angesprochen hast und dieser nur die Leute beleidigen kann soll er dir auch helfen.

Aus deinem indizierten *.png im Speicher 24Bit erstellt und extrem vergrößert bzw. auf mein Fenster angepasst.
Nicht mal 5 Minuten Arbeit.

Damit du nicht denkst es wäre ein fake habe ich noch 2 Bitmaps drüber gelagert.
Es ist dein Paletten Bild unverändert. (1 Bit). Einfach nur als Hintergrund geladen

Ich werde das Thema nun verlassen.
Schönen Tag noch.

Geändert von venice2 (20. Okt 2020 um 12:13 Uhr)
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.010 Beiträge
 
Delphi 2009 Professional
 
#48

AW: PNG in TImage falsch dargestellt

  Alt 26. Apr 2020, 22:31
Hab mir das nochmal angesehen:
  • Paletten-PNG an sich kennt überhaupt keine 1-Bit-Transparenz. Dies ist nur ein Spezialfall von Palette+Alphakanal, wo alle Alphawerte entweder 0 oder 255 sind. TPngImage behandelt den Spezialfall anders (ptmBit) als Palette+Alphakanal (ptmPartial), obwohl es dafür keinen wirklichen Grund gibt. Man könnte jetzt versuchen, das Attribut TransparentColor zu verwenden, dies ist jedoch problematisch, da einen niemand daran hindert, beispielsweise die beiden Paletteneinträge Schwarz 0 Alpha und Schwarz 255 Alpha zu speichern. Dies in eine 24-Bit-PNG mit transparenter Farbe umzuwandeln und die transparente Farbe auf Schwarz zu setzen, funktioniert dann nicht.
  • Dein PNG 4 hat 256 Paletteneinträge, aber nur 77 Farben.
  • Dein PNG 4 enthält 256 Alphawerte. Der letzte ist völlig transparent. Eigentlich macht man das andersrum (erster Eintrag ist völlig transparent), damit man die restlichen nicht speichern muss, da man keine Alphawerte speichern muss, wenn alle folgenden Alphawerte komplett deckend sind.
  • Mein PNGDelphi in D2009 versagt bei 4-Bit- und 1-Bit-Paletten-PNGs.

Ich habe jetzt folgenden Code geschrieben. Der führt zumindest bei meinem PNGDelphi dazu, dass ein Paletten-PNG in True Color umgewandelt wird. Das funktioniert auch mit den bisher zumindest von meinem PNGDelphi nicht unterstützten 1- und 4-Bit-PNGs. Es gibt sogar 1-Bit- und 4-Bit-PNGs mit Alphakanal. Auch das wird unterstützt.
Delphi-Quellcode:
procedure Deindex(PNG: TPngImage);
var
  Chroma: array[Byte] of TPaletteEntry;
  Alpha, ScanlineSource, ScanlineTarget, AlphaScanline: PByteArray;
  DoAlpha: Boolean;
  NewPNG: TPngImage;
  y, x: Integer;
  BitDepth: Byte;
  Mask: Byte;
  x2: Integer;
  Shift: Byte;
begin
  AlphaScanline := nil; // Compiler-Mimimi
  Alpha := nil; // Compiler-Mimimi
  if PNG.Header.ColorType = COLOR_PALETTE then
  begin
    DoAlpha := PNG.TransparencyMode <> ptmNone;
    if DoAlpha then
    NewPNG := TPngImage.CreateBlank(COLOR_RGBALPHA, 8, PNG.Width, PNG.Height)
    else
    NewPNG := TPngImage.CreateBlank(COLOR_RGB, 8, PNG.Width, PNG.Height);
    try
      GetPaletteEntries(PNG.Palette, 0, 256, Chroma);
      BitDepth := PNG.Header.BitDepth;
      Mask := Word(1) shl BitDepth - 1;
      if DoAlpha then
      Alpha := @((PNG.Chunks.FindChunk(TChunktRNS) as TChunktRNS).PaletteValues); // hier bin ich mir unsicher in Sachen Speicherverletzung
      for y := 0 to PNG.Height - 1 do
      begin
        ScanlineSource := PNG.Scanline[y];
        ScanlineTarget := NewPNG.Scanline[y];
        if DoAlpha then
        AlphaScanline := NewPNG.AlphaScanline[y];
        for x := 0 to PNG.Width - 1 do
        begin
          x2 := x * BitDepth div 8;
          Shift := 8 - BitDepth - ((BitDepth * x) mod 8);
          ScanlineTarget^[x*3 ] := Chroma[(ScanlineSource^[x2] shr Shift) and Mask].peBlue;
          ScanlineTarget^[x*3+1] := Chroma[(ScanlineSource^[x2] shr Shift) and Mask].peGreen;
          ScanlineTarget^[x*3+2] := Chroma[(ScanlineSource^[x2] shr Shift) and Mask].peRed;
          if DoAlpha then
          AlphaScanline^[x] := Alpha[ScanlineSource^[x2] shr Shift and Mask];
        end;
      end;
    except
      NewPNG.Free();
      raise;
    end;
    PNG.Assign(NewPNG);
    NewPNG.Free();
  end;
end;
Nur damit du siehst das es geht von wegen (So große Töne spucken)
ABer da du Herrn Redeemer angesprochen hast und dieser nur die Leute beleidigen kann soll er dir auch helfen.

Aus deinem indizierten *.png im Speicher 24Bit erstellt und extrem vergrößert bzw. auf mein Fenster angepasst.
Nicht mal 5 Minuten Arbeit.

Damit du nicht denkst es wäre ein fake habe ich noch 2 Bitmaps drüber gelagert.
Es ist dein Paletten Bild unverändert. (1 Bit). Einfach nur als Hintergrund geladen

Ich werde das Thema nun verlassen.
Schönen Tag noch.
Kann ich auch mit Grafiksoftware, APIs (in deinem Fall LEAD Technologies) oder anderweitig ohne Delphi machen. Dass du es mit Delphi gemacht hast, dafür gibt es keine Hinweise.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
627 Beiträge
 
Delphi 11 Alexandria
 
#49

AW: PNG in TImage falsch dargestellt

  Alt 27. Apr 2020, 13:43
@OP
Hast du denn nun schon mal die VCL.Imaging.PNGimages.pas in dein loakels Anwendungsverzeichnis kopiert und die beiden von mir erwähnten Zeilen gelöscht und neu kompiliert?

@venice2
TImage und TPNGImage haben nichts miteinander zu tun. TPNGImage ist die Grafikklasse (TGraphic), die ein PNG Bild rendert und darstellt. TImage ist eine allgmeine Darstellungskomponente (TControl), die nichts anderes macht als die Paint Funktion der geladenen Graphic-Klasse aufzurufen. Dieses Problem hier hat mit der TImage Komponente nichts zu tun, sondern betrifft die Implementation der TPNGImage Klasse.
  Mit Zitat antworten Zitat
tumo

Registriert seit: 28. Apr 2014
46 Beiträge
 
Delphi 10.3 Rio
 
#50

AW: PNG in TImage falsch dargestellt

  Alt 27. Apr 2020, 17:13
@Rolf Frei
Ach ja. Das ist im Eifer des Gefechtes etwas in Vergessenheit geraten. Hab es gerade mal probiert, ändert leider nichts an der Situation, besagte PNG wird mit schwarzem Hintergrund dargestellt :/.
Hier mein Quellcode:
Delphi-Quellcode:
png := TPNGImage.Create;
    png.LoadFromFile(Path);
    bmp := TBitmap.Create;
    bmp.Assign(png); // <-- TPNGImage AssignTo() ist modifiziert. Es fehlen das Brush.Color := 0 sowie das FillRect.
    Image3.Picture.Graphic := bmp;
@Redeemer
Dieser Code funktioniert . So oder so ähnlich hätte ich es natürlich auch gelöst . Spaß beiseite, vielen Dank!
Dass die Bilder nicht optimal gespeichert sind, hab ich auch schon gemerkt. Wie gesagt, manche sind mir so gegeben, andere sind von mir in Paint.net erstellt, keine Ahnung, warum es da solche Späßchen generiert.

Jetzt hat das Problem einen Workaround. Warum Delphi überhaupt eine Unterscheidung zwischen Partial- und BitTransparency macht, bleibt mir ein Rätsel. Hat das einen entscheidenden Vorteil?
Mein Problem ist jetzt jedenfalls behoben bzw. umgangen. Danke euch.

Habe es jetzt folgendermaßen gelöst (mit der Prozedur von Redeemer):
Delphi-Quellcode:
var
  gfx: TPicture;
begin
  gfx := TPicture.Create;
  gfx.LoadFromFile(Path);
  if gfx.Graphic is TPNGImage then
    Deindex(gfx.Graphic as TPNGImage);
  Image3.Picture.Assign(gfx);
end;
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 12:24 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