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.