Ich muss meine Aussage von vorhin korrigieren: Mir fällt nämlich auf, dass der von mir beschriebene Bug nur mit TImageList.AddMaked(BMP, clNone) und InsertMasked auftritt (ReplaceMasked unterstützt allgemein keine Alphakanäle), nicht jedoch mit TImage, während mein Bugfix (Kopieren der Scanline-Bytes) in TImageList fehlerfrei funktioniert aber in TImage unter bestimmten Umständen zu einem extrem lustigen Fehler führt (siehe *):
- | Einfach nur Original-Assign | mit Korrektur von Rolf | mit manuellem Kopieren der Scanline-Bytes | mit manuellem Kopieren der Scanline-Bytes und Korrektur von Rolf |
TImage.Picture.Graphic := BMP | fehlerfrei mit fehlerfreiem Alphakanal | zu Weiß geglättet komplett ohne Alphakanal | siehe * | Alphakanal wird komplett ignoriert, also alle Pixel in gespeicherter Farbe vollständig deckend |
TImageList.AddMasked(BMP, egal) | zu Schwarz geglättet mit fehlerfreiem Alphakanal | zu Weiß geglättet komplett ohne Alphakanal | fehlerfrei mit fehlerfreiem Alphakanal | Alphakanal wird komplett ignoriert, also alle Pixel in gespeicherter Farbe vollständig deckend |
* ohne RDP: Die TBitmap zeichnet sich selbst wie folgt auf den Hintergrund, auf dem das TImage liegt: Pixel mit Deckkraft > 0 haben korrekten Alphakanal. Bei Pixeln mit Deckkraft = 0 wird für jeden Kanal einzeln (d.h. ohne Überlauf) der Kanal zum jeweiligen Kanal des Hintergrunds addiert. Das sieht lustig aus, tritt aber normalerweise nicht auf, da die meiste Software es nicht erlaubt, Farben außer Schwarz in transparenten Pixeln zu speichern, und Schwarz fehlerfrei dargestellt würde (Hintergrund + clBlack = Hintergrund).
* in einer RDP-Sitzung: Bild zeichnet nicht vollständig deckende Pixel zwar mit korrektem Alphakanal, aber als ob die Farbe des in der PNG gespeicherten Pixels komplett schwarz wäre. Vollständig deckende Pixel sind fehlerfrei.
GDI macht über RDP wirklich was es will.
Mich wundert vor allem, dass TCanvas.Draw überhaupt den Alphakanal des Zielbitmaps schreibt. In TPNGImage.Draw wird in dem Fall TPNGImage.DrawPartialTrans aufgerufen, das wahrscheinlich eine Spezialbehandlung für Bitmaps bietet, die ich aber nicht verstehen/finden kann.
Und mich wundert, dass frischt assignte Bitmaps in TImage fehlerfrei dargetellt werden, in TImageList aber nicht. Die Daten müssen also irgendwo fehlerfrei vorhanden sein.
Auch seltsam: Der zweite Parameter von AddMasked wird in allen oben getesteten Fällen ignoriert.
Ich hab mal mein Beispielprojekt angehängt. imagelist.png enthält drei 16x16-Bilder nebeneinander:
- weißer Kreis, linke Hälfte ist nur 50% deckend
- schwarzer Kreis, linke Hälfte ist nur 50% deckend
- die 16 Standardfarben in der unteren Hälfte sind in der oberen Hälfte mit 0 Deckkraft gespeichert
Das enthaltene Kompilat ist aus D2009 (sieht bei D10.3 genau so aus, ebenso unter Windows 10) und stellt den Zustand aus der vorletzten Spalte (mit manuellem Kopieren der Scanline-Bytes). Davon habe ich auch zwei Bilder angehängt (jeweils ohne RDP).
(Ich weiß, dass der Code Memoryleaks hat.)