Skip to content

Virtual image collection

Lübbe Onken edited this page Aug 16, 2021 · 6 revisions

A correct use of "virtual" components (VCL)

TImageCollection and TVirtualImageList (available from From Delphi 10.3)

A high DPI aware application should be able to provide icons fitting several different DPI factors. Therefore it is important to separate the concept of “size” from the concept of “appearance”. Starting with Delphi 10.3, two new components are available to be used instead of TImageList: TImageCollection and TVirtualImageList.

TImageCollection

This component collects a list of “Bitmap” images. It is possible to load them from files (of many formats and sizes) in order to populate the collection. Usually, the component is put onto a TDatamodule in order to be available for use by all the application forms needing it.

TVirtualImageList

In order to make use of icons contained in a TImageCollection, you need a TVirtualImageList component. You can place it on each form and make it reference the Collection. The TVirtualImageList component states the size (Width and Height) of the icons to be included, but it is important to keep in mind that this size is always to considered with respect to a screen with 96 DPI.

The advantage of placing a VirtualImageList on each form also consists that you can choose “only” the images you need in that specific context: in the following example you can see we added only 5 of the images in the collection. You can even sort them in different positions, because they are referenced by name (and not by position). You can also set a category for the icons: in fact the icon will be called “category \ name” (eg “account \ ic_account_box”) even if, unfortunately, the categories defined in the TImageCollection are not automatically fetched while adding images to the VirtualImageList.

Limitations in the use of Bitmap images

The major limitation of TImageCollection is a consequence it uses bitmap images of “fixed” size. This brings a number of consequences:

  • you need to provide icons at different resolutions and to load them all into the collection. This causes useless occupation of memory and resources (all bitmaps in all resolutions) with the possibility most of them will never be used in the life cycle of the application;
  • you rely on “rescaling” algorithms when an icon size not matching those available in the collection is required;
  • you need to double the effort in order to provide the application with a light / dark theme mechanism. Furthermore, you may even need to provide several set of icons (of different color schemes) in order to match the actual VCL style selected by the user.

The solution? SVGIconImageCollection + VirtualImageList

You can solve all of this problems using the components of this library because the TSVGIconImageCollection is fully compatible with TVirtualImageList.

If you are using an older version of Delphi, you can use the TSVGIconVirtualImageList instead of the native TVirtualImageList: an important difference is that TVirtualImageList may use and create only a subset of the images in the collection, whereas TSVGIconVirtualImageList creates all images of the collection every time it is needed (e,g. DPI change), which is slower and consumes more memory: we advise that TSVGIconVirtualImageList should be used only for versions of Delphi before 10.3.

Although TVirtualImageList does not have the FixedColor, GrayScale and Opacity properties, these properties exist at the TSVGIconImageCollection and they would be reflected on the linked TVirtualImageList.

Don't forget also the importance of PreserveItems when you have a large ImageCollection with many linked Actions. Without setting this property to "True", every time you add or remove an icon in the collection, you have to check and change the ImageIndex of all the Actions.

Pointing icons by name

From Delphi 10.4.1 you can use the "image name" of the icon to link it to the other components (Action, Menuitem, ToolButton...) so you can update your collection with new icons also in the middle of the collection (changing it's ImageIndex) without losing the link from the collection to the VirtualImageList and other components.