Danke für die tollen Ideen!
Also, gehen tut das. Siehe angehängter Screenshot aus einem Programm von mir, das das allerdings mit TPNGImage und Scanline macht.
Sehr gut zu wissen.
Ich dachte immer, Delphi würde die Bilder intern im Speicher alle als (T)Bitmap behandeln? Damit dürfte die Frage TPNGImage/Scanline also egal sein. Aber wenn ich es nicht hinbekomme, würde mich diese Lösung dennoch interessieren.
Völlig richtig. Die PNGs werden nach Erstellung in TBitmaps umgewandelt. Das normale
Assign
hat hier einen Bug, dass ein Alphablending zu schwarz stattfindet, halbtransparente Bereiche werden also dunkler. Daher kopiere ich zusätzlich (Alphakanal funktioniert ja) die Farbdaten noch einmal per Scanline. TPNGImage unterscheidet sich von TBitmap vor allem darin, dass Scanline und Alphascanline getrennt werden.
/Edit: Der vorherige Absatz war Blödsinn, daher korrigiert.
Hier die Funktion, falls sie jemand braucht:
Delphi-Quellcode:
function PNGToBMP(PNG: TPngImage; const Free: Boolean = False): Graphics.TBitmap;
var
i, j: Integer;
begin
// Fixes a bug that causes BMP transparency to look very dark und ugly for
// areas after conversion to BMP
Result := Graphics.TBitmap.Create;
Result.Assign(PNG);
if PNG.Header.ColorType = COLOR_RGBALPHA then
for i := 0 to PNG.Height - 1 do
for j := 0 to PNG.Width - 1 do
begin
TByteArray(Result.ScanLine[i]^)[j*4] := TByteArray(PNG.Scanline[i]^)[j*3];
TByteArray(Result.ScanLine[i]^)[j*4+1] := TByteArray(PNG.Scanline[i]^)[j*3+1];
TByteArray(Result.ScanLine[i]^)[j*4+2] := TByteArray(PNG.Scanline[i]^)[j*3+2];
end;
if Free then
PNG.Free;
end;
Kleiner Tipp, den du mal probieren kannst:
- Fülle die Bitmap in der transparenten Farbe
- Zeiche des Bild darauf
Genau so mache ich es schon
- Setze jetzt erst die Transparenzeigenschaften und zwar nur, wenn NH bzw. NW <> ThumbSize
Das ist prakisch immer der Fall. Die Bilder kommen mit mind. 200 dpi rein. Bei DIN-A4 sind das also immer mind. 1600 Pixel, während ThumbSize 144 ist.
- Setze Transparenzmodus auf automatisch oder gar nicht (gerade nicht sicher)
- Nutze ImageList.AddMasked mit deine transparenten Farbe
Und hier gehen jetzt meine Fragen los:
Transparezmodus meint vermutlich
TImageList.DrawingStyle
? Da gibt es "nur"
TDrawingStyle = (dsFocus, dsSelected, dsNormal, dsTransparent);
(
Vcl.ImgList).
Tmagelist.AddMasked(aBMP, clTrans);
führt dazu, dass der weiße Hintergrund nicht mehr blau ist. Allerdings bleiben die Bilder faktisch quadratisch. Und
das zweite Problem besteht darin, dass sich diese Thumbnails ändern können. Deshalb bin ich leider auf
TImageList.Replace(ImageIndex, aBMP, MaskBMP);
angewiesen. Und hier finde ich leider nichts bzw. nichts einfach verständliches, wie man ein solches MaskBitmap "richtig" anlegt.
Es wäre also wirklich toll, wenn Du mir den Trick verraten würdest, wie Du/man diese TListView bastelst, in der die blaue Farbe bei ausgewähltem Bild bis ans Bild heranreicht.
Falls es noch eine Rolle spielt. Aktuell habe ich das mit XE5 kompiliert. Nicht dass es da irgend einen Bug gibt, der mir das ganze evtl. vermiest. Man weiß ja nie.
Habe das jetzt so gemacht, wie ich das beschrieben habe und es funktioniert. Lösung ist angehängt. Lösung für replace weiß ich derzeit nicht, musst du vielleicht lösen, indem du stattdessen die ImageIndexes anpasst.