![]() |
Wie verwendet man die neue TVirtualImageList
Wie verwendet man die neue TVirtualImageList? Ich verstehe noch nicht so rich tig was die überhaupt soll, wofür die ImageCollection ist, warum man die im OI mit der VirtualList verknüpft und noch mehr. Mein erster Versuch geht in die Hose
Delphi-Quellcode:
Auf der Form habe ich TVirtualImageList und TImageCollection1. Alle Icons sind im TImageCollection und komischerweise auch im TVirtualImageList. Sieht aus wie unnötige doppelte Arbeit.
Image1.Picture.Icon := VirtualImageList1.Images.Items[ImageCollection1.GetIndexByName('icon')];
|
AW: Wie verwendet man die neue TVirtualImageList
Die beiden Komponenten spielen ihre Vorteile eigentlich erst dann aus, wenn es um High DPI geht. Die ImageCollection hält zunächst erstmal nur die Icons, gegebenenfalls auch in unterschiedlichen Größen. Die VirtualImageList holt sich ihre Icons aus der ImageCollection in der Größe, die sie gerade braucht. Damit wird eine automatische Anpassung an unterschiedliche DPI Werte ermöglicht. Damit das funktioniert muss die VirtualImageList zwingend auf ein Form platziert werden. Das Form bemerkt die DPI Änderung und benachrichtigt die VirtualImageList. Diese besorgt sich dann die Icons in der passenden Größe von der ImageCollection, die bei Bedarf auch skaliert wenn die passende Größe nicht vorhanden ist.
Dein Code-Beispiel
Delphi-Quellcode:
Image1.Picture.Icon := VirtualImageList1.Images.Items[ImageCollection1.GetIndexByName('icon')];
kann so nicht funktionieren, da Images.Items kein TIcon oder TBitmap zurückliefert, sondern ein TVirtualImageListItem. Es übrigens auch gar nicht nötig, über die VirtualImageList zu gehen. Das Icon bekommst du wesentlich bequemer direkt aus der ImageCollection. Dabei gibst du gleich die Größe an, in der du es haben willst.
Delphi-Quellcode:
Image1.Picture.Graphic := ImageCollection1.GetSourceImage(ImageCollection1.GetIndexByName('icon'), 256, 256);
|
AW: Wie verwendet man die neue TVirtualImageList
Ich benutze aktuell deine PngImageList mit mehreren Helpern. So gesehen benutze ich 5 PngImageLists mit 5 verschiedenen Icongrößen.
Über eine eigene Prozedur lasse ich mir dann das Icon zurückgeben was ich brauche. Was gebraucht wird, übergebe ich in den Parametern.
Delphi-Quellcode:
HighDPI wird auch die nächsten Jahre an mir vorbei gehen. Danke für deine Erklärung. Habe demnach keinen Gebrauch für diese neue Komponente.
procedure ... LoadIcon(const AName: string; IconSize: TIconSize; Icon: TIcon);
begin case IconSize of is16: Icons16.LoadImageByName(AName, Icon); is32: Icons32.LoadImageByName(AName, Icon); is48: Icons48.LoadImageByName(AName, Icon); is64: Icons64.LoadImageByName(AName, Icon); is128: Icons128.LoadImageByName(AName, Icon); end; end; |
AW: Wie verwendet man die neue TVirtualImageList
ein..
Delphi-Quellcode:
wäre nicht schlecht ist ja fast schon Standard.
is256:
Icons256.LoadImageByName(AName, Icon); gruss |
AW: Wie verwendet man die neue TVirtualImageList
Wo sollte ich das denn benutzen? Wenn ich an einer Stelle an 16x16 Icon brauche, nehme ich 16x16. Ich habe keine Stelle wo ich jemals 256 bräuchte.
|
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
Es sei denn deine Anwendungen laufen nur auf deinem System Privat.. dann kannst du das natürlich ignorieren. Wenn du also nur! Größen definierst die Dir zusagen und das System ist so eingestellt das es bei größeren Monitoren zum Beispiel 256 Icons anzeigt. Nun dann bist du leicht aufgeschmissen bzw.. es wird das maximal größte verwendet was dann vom System skaliert wird. War auch nur ein Vorschlag. :) gruss |
AW: Wie verwendet man die neue TVirtualImageList
Keine Ahnung was du meinst. Bei mir wird alles richtig angezeigt. Egal welche Auflösung und DPI.
|
AW: Wie verwendet man die neue TVirtualImageList
Wer UI-Grafiken 2018 als Rastergrafiken speichert, hat die Kontrolle über sein Leben verloren.
|
AW: Wie verwendet man die neue TVirtualImageList
Statt solche sinnlosen Sätze zu äußern wär ich dankbar wenn man wenigstens erklärt wie es anders geht.
Zitat:
|
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
|
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
|
AW: Wie verwendet man die neue TVirtualImageList
Dankeschön. Werde ich irgendwann mal versuchen.
|
AW: Wie verwendet man die neue TVirtualImageList
Moin Moin.
Etwas älterer Thread, Problem ist trotzdem noch da: Auf meiner Form habe ich ein TImageCollection Element plaziert und 163 PNG's in 128x128px geladen. Diese Collection wird dann in der TVirtualImageList angegeben das als Height/Width eine 32 hat. Infolge werden bei Controls wie dem Listview die optisch einwandfrei skalierten Bildchen als 32er angezeigt. Ein solch sauber skaliertes Bild möchte ich jetzt aber auch einem TImage zuweisen, wie ja die Kernfrage des Threads hier war. Die weiter oben angegebene Empfehlung wäre in meinem Fall
Delphi-Quellcode:
Was dann aber im Ergebnis wieder eine tödliche Bildqualität produziert weil ich für das TImage ja Stretch benutzen muss. Oder?
Image1.Picture.Graphic := ImageCollection1.GetSourceImage(ImageCollection1.GetIndexByName('icon'), 32,32);
Also hole ich mir via
Delphi-Quellcode:
das gewünschte Bild, das auch prompt und in guter Qualität kommt. Und natürlich ohne Transparenz, die ich benötige.
VirtualImageList1.GetBitmap(Main.VirtualImageList1.GetIndexByName('BILD'),Image1.Picture.Bitmap)
Frage : Wie kriege ich transparenz? Oder : wie überrede ich TImageCollection mir das Bildchen in hübsch skaliert abzuliefern? Für was ist sonst die Property InterpolationMode gedacht? creehawk |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
Delphi-Quellcode:
Image1.Picture.Graphic := ImageCollection1.GetSourceImage(ImageCollection1.GetIndexByName('icon'), Image1.Width, Image1.Height); |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
Aber wenn ich ein 32x32 Image habe und das so mache wie du sagst, wird ein Bild reingeladen was in etwa 48x48 groß ist. TImage auf Form und dann deine Zeile. Mehr nicht. Egal welche Größe ich als Parameter angebe. Das geladene Bild ist immer größer als das TImage. Mit TToolButtons auf einer ToolBar habe ich keine Probleme aus der VirtualImageList zu laden. Hat die ImageCollection überhaupt mehrere Größen der Bilder? Das hat doch nur die VirtualImageList. Irgendwie muss man diese neuen Listen doch auch auf ganz normale TImages anwenden können. Ich kann nicht überall ToolButtons hinhauen. |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
Kannst du mal konkret ein Beispielprojekt anhängen, mit dem man das mal nachstellen kann? |
AW: Wie verwendet man die neue TVirtualImageList
Liste der Anhänge anzeigen (Anzahl: 1)
Ja. Siehe Anhang
Die Schleife habe ich Vcl.ImageCollection.pas genommen (TImageCollection.GetSourceImageIndex) um zu sehen, was da eigentlich das Ergebnis ist. |
AW: Wie verwendet man die neue TVirtualImageList
In der Tat. GetSourceImage gibt einfach nur das nächst-größere Image zurück. In meinen Tests passte das zufällig.
Es gibt aber eine kleine Ergänzung, mit der das gewünschte Ergebnis erreicht werden kann:
Delphi-Quellcode:
type TImageCollectionHelper = class helper for TImageCollection public function GetScaledImage(AIndex, AWidth, AHeight: Integer): TWICImage; overload; end; function TImageCollectionHelper.GetScaledImage(AIndex, AWidth, AHeight: Integer): TWICImage; begin Result := GetScaledImage(GetSourceImage(AIndex, AWidth, AHeight), AWidth, AHeight); end; ... Image3.Picture.Graphic := Images.GetScaledImage(Images.GetIndexByName('krankenwagen'), Image3.Width, Image3.Height); ... |
AW: Wie verwendet man die neue TVirtualImageList
Also doch nicht ganz meine Blödheit. Danke dafür.
Ich frage mich wieso sowas nicht schon direkt in der Komponente enthalten ist. Ich finde es ist logisch, dass wenn man dem Aufruf Width und Height mit gibt, man auch nach Möglichkeit diese Größe haben möchte. |
AW: Wie verwendet man die neue TVirtualImageList
Ich merke gerade, dass es eine AV am Ende des Programms gibt. Besser gesagt ein Speicherleck was mit TWICImage zu tun hat. Wie bekommt man denn das weg?
Ein Image3.Picture.Graphic.Free; im FormDestroy bringt nur noch mehr Ärger. |
AW: Wie verwendet man die neue TVirtualImageList
Stimmt. SetGraphic macht ein Assign.
Delphi-Quellcode:
img := Images.GetScaledImage(Images.GetIndexByName('krankenwagen'), Image3.Width, Image3.Height); // img: TWICImage;
try Image3.Picture.Graphic := img; finally img.Free; end; |
AW: Wie verwendet man die neue TVirtualImageList
Ist es möglich img als var Parameter dem Aufruf mitzugeben um Zeilen zu sparen?
Weil ich ändere die Bilder öfter und nicht nur zum Programmstart.
Delphi-Quellcode:
procedure TImageCollectionHelper.GetScaledImage(AIndex, AWidth, AHeight: Integer; var Graphic: TGraphic);
var Img: TWICImage; begin Img := GetScaledImage(GetSourceImage(AIndex, AWidth, AHeight), AWidth, AHeight); try Graphic := Img; finally Img.Free; end; end; |
AW: Wie verwendet man die neue TVirtualImageList
Da Graphic ein Property ist, kann man das nicht als var-Parameter übergeben. Allerdings kann man noch einen anderen Class Helper schreiben:
Delphi-Quellcode:
type
TImageHelper = class helper for TImage public procedure UpdateImage(Source: TImageCollection; Index: Integer); overload; procedure UpdateImage(Source: TImageCollection; const AName: string); overload; end; procedure TImageHelper.UpdateImage(Source: TImageCollection; Index: Integer); var img: TWICImage; begin img := Source.GetScaledImage(Index, Width, Height); try Picture.Graphic := img; finally img.Free; end; end; procedure TImageHelper.UpdateImage(Source: TImageCollection; const AName: string); begin UpdateImage(Source, Source.GetIndexByName(AName)); end; ... Image3.UpdateImage(Images, 'krankenwagen'); ... |
AW: Wie verwendet man die neue TVirtualImageList
Moin Moin.
Etwas verspätet wieder am Platz, aber mein Router war abgeraucht. Ich bedanke mich ebenfalls für die Antwort(en) und Hinweise. creehawk |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
selbst wenn es das würde, dann wäre es Fatal die kopierte Referenz (Img) sofort freizugeben, und da es nicht möglich ist einen Property zu übergeben, sondern nur den wert aus/für dessen Getter oder Setter, ist VAR hier sowieso nutzlos. Du kannst aber TPicture als Parameter übergeben und darüber auf den Setter des Picture.Graphic zugreifen, oder z.B. wie im schon gezeigten ClassHelper, an TImage oder auch an TPicture, das .Graphic in der Methode benutzen. |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
Hast du schon mal in quality.embarcadero.com nachgeschaut ob die dort auch schon jemand gestellt hat? Falls nicht wäre es toll, wenn du das dort als Feature Request eintragen könntest und uns hier dann die Report Nummer verrätst, damit wir dafür stimmen können. Grüße TurboMagic |
AW: Wie verwendet man die neue TVirtualImageList
Gibt es sowas auch für Icon? Ich versuche mich hier gerade wieder dumm und dämlich.
Ich habe das aktuell so
Delphi-Quellcode:
type
TImageHelper = class helper for TImage public procedure GetImage(Source: TImageCollection; Index: Integer); overload; procedure GetImage(Source: TImageCollection; const AName: string); overload; end; type TImageCollectionHelper = class helper for TImageCollection public function GetScaledImage(AIndex, AWidth, AHeight: Integer): TWICImage; overload; end; implementation procedure TImageHelper.GetImage(Source: TImageCollection; Index: Integer); var img: TWICImage; begin img := Source.GetScaledImage(Index, Width, Height); try Picture.Graphic := img; finally img.Free; end; end; procedure TImageHelper.GetImage(Source: TImageCollection; const AName: string); var Index: Integer; begin Index := Source.GetIndexByName(AName); if Index > -1 then GetImage(Source, Index); end; function TImageCollectionHelper.GetScaledImage(AIndex, AWidth, AHeight: Integer): TWICImage; begin Result := GetScaledImage(GetSourceImage(AIndex, AWidth, AHeight), AWidth, AHeight); end; |
AW: Wie verwendet man die neue TVirtualImageList
Etwas weiter vorne war die Frage nach der Transparenz aufgekommen aber bisher nicht beantwortet. Wenn ich ein Bitmap aus der virtualcollection ziehe, dann werden die transparenten Bereiche schwarz gezeichnet (ich zeichne hier ein Symbol in ein Stringgrid).
Carsten |
AW: Wie verwendet man die neue TVirtualImageList
Falls hierzu mal wieder jemand knobelt:
Bitmap.alphaformat:=afDefined; muss man beim TBitmap setzen, bevor man es zeichnet. Geht zumindest für meine PNG-Dateien mit transparentem Hintergrund, die in einer VirtualImagelist einsortiert sind. Carsten |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
Genau wie die VirtualImageLists auf Ende auch nur Raster-Bitmaps sind. Aber FMX Images basierten schon auf "MultiBitmaps", welche sinngemäß den VirtualImageLists entsprechen, um genau diese HighDPI und "Retina" Probleme abzufangen. Das gab es schon standardmäßig als VCL noch gar nichts mit DPI anzufangen wusste :stupid: |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
![]() |
AW: Wie verwendet man die neue TVirtualImageList
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz