AGB  ·  Datenschutz  ·  Impressum  







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

[gelöst] Transparenz in TListView übernehmen

Ein Thema von Schwedenbitter · begonnen am 12. Okt 2017 · letzter Beitrag vom 13. Okt 2017
Antwort Antwort
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#1

[gelöst] Transparenz in TListView übernehmen

  Alt 12. Okt 2017, 23:34
Hallo,

ich befülle zur Laufzeit eine TImageList und lasse sie in einer TListView anzeigen. Leider sind das Bilder von einem Scanner, die in unterschiedlichen Größen und Formaten (Hoch- und Querformat) geliefert werden. Um alles abzudecken, erzeuge ich quadratische Thumbnails.
So weit, so gut.

Mich stört allerdings die Optik.
Ich probiere schon stundelang rum und habe unter anderem hier im Forum nachgelesen, an welchen Stellen man drehen kann. Allerdings finde ich keine Lösung.
Den Quellcode habe ich angehängt und 2 Bilder - ein Bild mit dem Ist-Zustand und ein (nachbearbeitetes), wie ich es gern hätte.

Kann man dieses Ziel überhaupt erreichen und - falls ja - wie?
Miniaturansicht angehängter Grafiken
ist-zustand.png   so_haette_ich_es_gern.png  
Alex Winzer

Geändert von Schwedenbitter (13. Okt 2017 um 14:04 Uhr) Grund: Das Problem wurde gelöst.
  Mit Zitat antworten Zitat
Redeemer

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

AW: Transparenz in TListView übernehmen

  Alt 13. Okt 2017, 08:07
Also, gehen tut das. Siehe angehängter Screenshot aus einem Programm von mir, das das allerdings mit TPNGImage und Scanline macht. Gerade habe ich nicht so viel Zeit, aber später kann ich mal schauen.

Kleiner Tipp, den du mal probieren kannst:
- Fülle die Bitmap in der transparenten Farbe
- Zeiche des Bild darauf
- Setze jetzt erst die Transparenzeigenschaften und zwar nur, wenn NH bzw. NW <> ThumbSize
- Setze Transparenzmodus auf automatisch oder gar nicht (gerade nicht sicher)
- Nutze ImageList.AddMasked mit deine transparenten Farbe
Miniaturansicht angehängter Grafiken
listview.png  
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Transparenz in TListView übernehmen

  Alt 13. Okt 2017, 09:14
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.

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.
Alex Winzer
  Mit Zitat antworten Zitat
Redeemer

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

AW: Transparenz in TListView übernehmen

  Alt 13. Okt 2017, 10:59
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.
Angehängte Dateien
Dateityp: pas _main.pas (4,8 KB, 7x aufgerufen)
Janni
2005 PE, 2009 PA, XE2 PA

Geändert von Redeemer (13. Okt 2017 um 17:13 Uhr)
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#5

AW: Transparenz in TListView übernehmen

  Alt 13. Okt 2017, 14:03
...
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 (Alphablending funktioniert ja) die Canvasses (CopyRect). TPNGImage unterscheidet sich von TBitmap vor allem darin, dass Scanline und Alphascanline getrennt werden.
...
Danke für den Code. Ich nutze PNG gerade nur, weil die Bilder dann weniger Speicher belegen als Bitmap und man so den Code samt Sourcen besser teilen kann.

...
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.
War gar nicht nötig.
Ich habe mir die Quellen nochmal angesehen. Dort gibt es eine Möglichkeit, neue Bitmaps inkl. Maskenfarbe mit ImageList1.InsertMasked(Idx, aBMP, clTrans); einzufügen. Man kann also entweder vorher das alte Bild löschen und das neue an dessen Position setzen oder man setzt erst das neue Bild dort rein und löscht das (dann) folgende Bild - letzteres schont wohl die Resourcen.

Ich habe den Code nebst Ersetzungsbild nochmal zum Testen angehängt. Danke für Deine ausführliche Hilfe!
Angehängte Dateien
Dateityp: zip ListView.Transparent.2.zip (106,3 KB, 6x aufgerufen)
Alex Winzer
  Mit Zitat antworten Zitat
Antwort Antwort


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 03:39 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