Delphi developers, please forget about TImage in VCL to display pictures

 

Table of contents

preamble

 Support for high resolution images using TImageCollection and TVirtualImageList components

1. Overview

Second, use the image collection component TImageCollection

2.1 Image Collection Component Editor

2.2 Load existing TImageList into TImageCollection

3. Use the Virtual ImageList component

3.1 Virtual ImageList Component Editor

4. Use the image component TVirtualImage under multi-resolution

5. Best Practices

5.1 Multiple sizes

5.2 Support high DPI in application and convert legacy TImageLists

5.3 Smooth scaling when drawing on TCanvas


preamble

        Delphi developers know that TImage will be used to display pictures, which is very convenient and supports many picture formats. However, with the development of technology today, high-resolution displays (4K 3840x2160) have gradually become popular, so TImage seems powerless. It’s not that it can’t be displayed, TImage can display the image normally according to the actual size whether it is on a 2K resolution or a 4K resolution monitor. However, if we display an image on a 4K resolution, it feels that the ratio can be adjusted, but when it arrives On 2K (1920x1080), the image feels doubled. As shown below:

  

         Note that the program developed at 4K resolution (left picture) runs at 2K resolution, and the picture displayed by TImage is obviously 2 times larger. This means that TImage does not support automatic scaling and display consistent functions under multiple resolutions. So which control can be realized, which is the TVirtualImage control in the above figure, which can fully realize automatic scaling at different resolutions, so as to achieve a consistent UI effect.

Most delphi developers may not have used the TVirtualImage control. This film introduces the relevant controls for displaying Delphi images in high-definition resolution. Delphi 11 began to support high-resolution displays, including the development environment IDE .

 Support for high resolution images using TImageCollection and TVirtualImageList components

1. Overview

        Using the TImageCollection component in conjunction with the TVirtualImageList component, RAD Studio can include scaled, high-DPI, and multi-resolution images in Windows VCL applications.

Please note

        If you're using FireMonkey in a cross-platform application, see the TImageList Component and the FireMonkey guide to Using TImageLists as a Central Image Repository.

These paired components distinguish the concept of a collection of images (each logical image can have multiple resolutions) from a list of images of a single specific size for a control. In short, load images of multiple resolutions into an image collection. An image list contains a set of images from an image set and is displayed at a specific size (eg 16x16). Images are resized and scaled smoothly, and the actual display resolution of the image list can vary according to DPI. It is fully compatible with traditional image lists and can directly replace traditional image lists, including providing HIMAGELIST handles, VCL controls and any code that uses Windows API image list calls can use it.

Images support alpha channels and can load PNGs into image sets. You can also load legacy color keyed transparency bitmaps.

Second, use the image collection component TImageCollection

With TImageCollection, native format images can be stored, scaled, and drawn using the native TWICImage class.

Each image in a collection can have multiple versions in different sizes. The component chooses the best size to scale, or uses the image when the available size equals the desired size. It can also create a scaled version of the 32-bit TBitmap with an alpha channel, which can be added directly to the TCustomImageList.

TImageCollection inherits from TCustomImageCollection class (Vcl.BaseImageCollection unit), which defines the basic methods of the collection.

2.1 Image Collection Component Editor

To open the image collection editor, place a TImageCollection on a form or data module, then double-click the component in the form or right-click the component and select the " Show collection editor… " option from the context menu. You can also double-click the TImageCollection.Images property in the Object Inspector. Of course, it can also be imported from the TImageList control through the right-click menu " Load from existing TIamgeLists ".

In the Image Collection Editor window, you can add images to components and organize them into categories.

Click Add to display the Open dialog and browse to the folder where the pictures are stored. You can add one picture at a time, or select multiple pictures from a folder to add at the same time. Image Collection Editor displays images in alphabetical order.

When adding images, you may need to add multiple sizes of the same image. For example, you might have a pixel resized 16x16 version of an image, and then have a larger image that needs to be drawn and scaled to other dimensions. You can do this by giving multiple versions of a single image the same filename, with a separator such as a hyphen, followed by a number representing the size in pixels: for example, foo-16.png and foo-64.png. Then check the "Check size in filename" checkbox and from the drop down option change Image Size Separator to the character that the image uses to separate the common name from the image size (in the previous example a hyphen "-") . This automatically recognizes multiple resolutions of the same image with similar filenames but different pixel sizes and adds them to the collection as multiple resolutions of a single image.

The Image size separator setting controls how parsing separates common names and image sizes, and includes options for common icon and image size filename conventions.

Notice:

        The Image Collection Editor requires separators in the numbering of filenames in order to identify different sizes of the same image.

Classification is currently only used for organizations. (In VCL controls, images can still only be referenced by index).

To organize images by category, select an image and click Set Category .

Use the " Delete " button at the top to delete a specific image from the collection, and the " Clear " button to delete all images in the collection.

Please note: When removing an image from the collection, VirtualImageList looks for the image by index.

After adding an image to a collection, you can select any available image and do the following: 

  • Modify the image Name .
  • Specify a custom Description for the image .
  • Specify an index value to modify the order of the images in the image set.
  • Add other sources for the same image .
  • Delete the source of the image.
  • Replace replaces the existing source of the image.

Please note

        When renaming and replacing images, follow these steps: 

  • Change index[name] and apply changes (VirtualImageList updates image by index[name] with name[index] from collection).
  • Change name[index] and apply changes (VirtualImageList updates image by name[index] using index[name] in collection).
  • Save the image with a different name ( save as . . . ).

Tip: You can also click and drag the image to a different position to modify its index value .

2.2 Load existing TImageList into TImageCollection

To help transition legacy image lists to the new system, you can load images from the old TImageList into a TImageCollection. When you have multiple sizes of the same image in different TImageLists, you can load both images at the same time; the images are merged so that the image collection contains multiple resolutions of the same image.

To load the pictures in TImageList into TImageCollection, you need to put these two components in the same form.

Follow the steps below to load images from an existing TImageList in a form into a TImageCollection: 

  • Right-click on the TImageCollection component in the form and select the From Existing TImageList... option from the context menu.
  • Select the TImageList to load, and specify a category for the image. You can select multiple TImageLists. This is especially useful for loading multiple resolutions of the same image previously stored in multiple image lists.

  • Click " Load in order  " to load the images in the same order as the images list.
  • Click Load with merging to merge different image sources from different image lists. When loading merged, the image lists must have the same number of image files and different image sizes.

  • Click View Collection... to verify the import of the image in the TImageCollection without closing the dialog.
  • Click OK to apply the settings and close the dialog.
  • Click Apply to apply a specific set of changes and continue configuring settings.
  • Click Cancel to close the dialog and discard all changes to the image set.

Please note

        After importing a TImageCollection or TVirtualImageList from a traditional TImageList, if you find that the image does not render correctly, such as white edges or other artifacts, check the ColorDepth property of the TImageList. Sometimes the ColorDepth property of an FMX TImageList is set to cd32Bit when the image it holds is actually 24-bit or 16-bit. Make sure the ImageList's color depth is set to cd32Bit if the bitmap it holds is true 32-bit, including the alpha channel.

3. Use the Virtual ImageList component

TVirtualImageList allows you to generate a list of images and apply changes to all images at the same time.

TVirtualImageList uses TCustomImageCollection (TImageCollection) to generate a dynamic list of internal images.

With TVirtualImageList, you can set custom width and height properties, and the component will automatically scale all images. When the DPI is changed, it scales the image to display properly on high DPI monitors.

Notice:

        A TVirtualImageList automatically inherits the DPI of its owner (TCustomForm or TCustomFrame) when scaled.
Since TVirtualImageList inherits from TCustomImageList, VCL controls can use TVirtualImageList without modification.

Notice:

        To add, insert and/or replace bitmaps in a TVirtualImageList, you must use the Add, Insert and/or Replace Items from ImageCollection methods.

3.1 Virtual ImageList Component Editor

To use the Virtual ImageList component and component editor, you first need to set the ImageCollection property in the object properties.

 

To open the VirtualImageList virtual image list editor, double-click the component in the form, or right-click the component and select the " Show image list editor… " option from the context menu .

If the AutoFill (autofill) property is set to True, the virtual image list will be automatically filled with all images in the collection. Otherwise, you can manually add images from the collection to the list using the image list editor.

 VirtualImageList The virtual image list editor window allows you to add images to components, including disabled versions of images, and organize them into categories.

Click Add to open the associated image set and select the images to include in the virtual image list. You can select specific images from an image collection, or select all images from an image collection or an existing category.

Additionally, the virtual image list editor window has the following options: 

  • Add Disabled: Allows you to create and add a low opacity or grayscale version of the selected image. The appearance of disabled images is controlled by the DisabledGrayscale and DisabledOpacity properties of the image list.
  • Add with Disabled Copy: Allows you to add an image from a related image set and at the same time create and add a disabled version of the selected image.
  • Replace: Allows you to replace the selected image.

Notice

        An image in the virtual image list component can only be replaced with an image in the image collection component, and the image is not in the previously added image list.

  • Set Category: Allows you to categorize images into categories. To create a category, select the images you want to include in the category and click "Set Category...", enter a category name, and click OK to display it in the categories list. The component editor will add the category name to the image name.
  • Make All Disabled: Turn previously added images into disabled images.

 

After adding the image to the virtual image list component, you can do the following: 

  • Reload:  Reload image name and description from ImageCollection.
  • Delete: Deletes the selected image from the virtual image list component.
  • Clear:   Deletes all images in the collection.
  • Name:   Modify the image name.
  • Description:   Specify a custom description for the image.

4. Use the image component TVirtualImage under multi-resolution

The TVirtualImage component supports multiple resolutions like the TImage component. The image source comes from the image collection (ImageCollection), which can have multiple resolutions depending on the screen DPI. The component will use the appropriate version based on the displayed display.

Some configuration settings and key properties of the VirtualImage component are as follows: ImageCollection, ImageHeight, ImageIndex, ImageName, and ImageWidth.

 When you use bitmap scaling logic to smoothly draw any VCL TGraphic (such as StretchDraw), there is a TScaledGraphicDrawer class that enables HQ scaled drawing for different TGraphic classes, called as follows: 

MyBitmap.EnableScaler(TD2DGraphicScaler);
Image1.Picture.Graphic.EnableScaler(TWICGraphicScaler);

Different solutions provide a combination of better or worse rendering and slower or faster performance. You can write custom TScaledGraphicDrawer derived classes that define additional scaling algorithms.

5. Best Practices

The TVirtualImageList component scales according to the DPI of the form it is placed on. This way, controls drawn with the image list on the form will always be drawn at the correct scaled resolution. However, this means two things: 

  • Controls should always reference an image list on the same form. If a control references an image list on a different form, the image may draw incorrectly when the two forms have different DPIs (such as on different screens).
  • TVirtualImageList should always be placed on the form, not the data module. Forms have an associated display and DPI, data modules do not. TImageCollections can be placed anywhere because they are just the source and are not affected by DPI changes: they are the source and the TVirtualImageList virtual image list is the rendering.

Therefore, if a control on a form uses image lists, you should always place one or more TVirtualImageLists on the form, and have the control refer only to these local image lists of the same form. These TVirtualImageLists can all refer to the same TImageCollection.

The Virtual Image Collection is a very useful control that distinguishes the concept of a collection of images (TImageCollection) from a collection of images of a specific size (albeit scalable with DPI) (TVirtualImageList). The image collection is not affected by DPI changes because it is just a container. TVirtualImageList A virtual image list can refer to an image in another form or TImageCollection image collection on a data module. A good design is to have an image collection for related images (such as all toolbar and menu images) on the application's main form or shared data module. The other forms will have their own virtual image lists that use the central image set.

5.1 Multiple sizes

        If you need multiple sizes of the same image, such as a TListView with SmallImages and LargeImages properties, use two TVirtualImageLists, just like traditional TImageLists. Both virtual image lists will reference the same image collection.

5.2 Support high DPI in application and convert legacy TImageLists

It is common to convert VCL applications from using TImageLists to TVirtualImageLists, which improves visual quality and helps support high DPI.

TVirtualImageList is a descendant of TCustomImageList, so it can be directly replaced at the code level, and also provides a HIMAGELIST Handle property for directly calling Windows API methods.

There are two recommended methods for converting an application to use the new high-DPI image list.

  1. First, you might upgrade your icons at the same time, from old-style icons to more modern ones, or from color-transparent icons to 32-bit images with an alpha channel. If you do this, you may find it easiest to just add the icons to a new image collection, create a new image list, and then change the component to point to the new image list.
  2. Second, you may want to upgrade incrementally, gradually replacing old images, or not at all (although we recommend taking advantage of the 32bpp alpha channel support in newer systems). To do this, place a TImageCollection, then right click and select Load from existing TImageList(s). Select the Image list and choose Add Image or Merge Images if they contain multiple resolutions of the same image. See TImageList to TImageCollection, Loading an existing TImageList into a TImageCollection for complete information.

This will make your image set contain old images. While using the old image won't improve the image quality or transparency as much as using the new design, it does allow the image to scale according to the DPI of each form. Create new TVirtualImageList components on each form, and add images from the collection: they will remain in the same relative order, so the index will be the same unless there are already images in the collection. Then, change the component to use the new TVirtualImageLists.

5.3 Smooth scaling when drawing on TCanvas

TCanvas.StretchDraw Allows TGraphic to be drawn onto an arbitrary rectangle. While the implementation of the TGraphic subclass determines how this is done, in practice VCL drawings (such as TBitmap) often use neighbor resampling via GDI, which often does not achieve ideal scaled or stretched image quality.

You can use TImageCollection to hold images (stored internally as and drawn with WIC) and draw them as arbitrary rectangles. Doing so will use high quality resampling.

Please give up TImage to display pictures, please use TImageCollection, TVirtualImageList, TVirtualImage

You will keep up with the steps of 4K!

Guess you like

Origin blog.csdn.net/sensor_WU/article/details/131909849