Using ImageList with multiple scales

ImageList(TImageList) is an image repository. We can store in it as many images as we want and in any format supported by the language, but generally we will use Bitmap(.bmp), Portable Network Graphics (.png) and JPEG (.jpg or .jpeg).

There is a big difference between Delphi and Lazarus ImageList, while in Delphi all images in an ImageList need to have the same width and height definition, in Lazarus this is not. In fact, Delphi has the VirtualImageList that serves precisely to allow multiple resizing of the same group of images, however most programmers continue to use the old ImageList.

If you wish, you can see in practice the explanation of this video article:

How does ImageList work in Lazarus? More important than knowing how it works is first knowing where to anchor an ImageList component, most programmers have created the habit of including an ImageList in each form with the images you will need in that form, this logic is very good, however, if there are images that will be shared between many forms, for example to use inside buttons to indicate exit, print, add, remove, edit, etc… then you he must having an ImageList just for them, this will save work on program maintainability.

Where to put the Imagelist? The main form is where an incredible amount of components and programming code is, so adding something there is a complexity to be avoided so the best idea is to create a datamodule, this one has footprint less resource and complexity, so it's safe to use it instead of the main form.

Creating a data module

If you have one datamodule main in your program then ignore this part, otherwise in a new project go to File|New… and choose to create a datamodule:

Creating a datamodule to contain an ImageList

The next step is to drag an ImageList into the datamodule and then configure the maximum size of the height (height) and width (width), if 64×64 is informed, all the images that I deposit inside the ImageList can have a size of 48× 48, 32×32, 24×24, 16×16,…any definition you want, but it cannot be larger than 64×64, so choose carefully the maximum size you want, after all if you need a different size you will have to erase all content and start from scratch again:

Carefully choose the first width and height setting, you won't be able to change it later without erasing the existing content

Including Images

Including images is very simple, right click on the Imagelist component and choose the option ImageList Editor:

And then include all your images, but attention, all images must be at least the size you defined before, in our example 64×64:

All added images must have the same definition as previously informed

Up to this point, you probably haven't seen anything else, it's just like you're used to. Now let's go back to the option ImageList Editor and we will add new resolutions by clicking new resolutions:

Now we can add new resolutions

If you initially informed your resolution as 64×64 then the new resolutions you will inform must be proportional and smaller than 64×64, so when a dialog window asks you what the new resolution will be, just inform the width and it will calculate the height. For example, to add the resolutions: 48×48, 32×32, 24×24 and 16×16, just enter 48, 32, 24 and 16 in sequence and they will be created in the proportion:

Adding new resolutions to previously added images

Now your ImageList, which previously only had images in 64×64 resolution, will now also have 48×48, 32×32, 24×24 and 16×16 images, but how can you use them within the program?

Using the images inside the ImageList

All visual components that allow their association with an ImageList component have the property images, what we need to do is the association of this component with the ImageList that is in datamodule. You will need to include the unit of the datamodule in your project's uses (Use Alt+F11) before proceeding:

Binding a component's Images property to the ImageList that is in the datamodule

Probably all that I said you already knew, now you want to know how to change the size of that image on the button, don't you? Note that every component that has a property images also has the property ImageWidth and ImageIndex:

In ImageWidth you can type 64, 48, 32, 24 and 16, all those resolutions we added to the ImageList, after that just select on ImageIndex the image you need:

Having defined the width we need, now we just have to choose the appropriate ImageIndex

If we need different images in different proportions, we just need to always adjust the property ImageWidth:

Demonstration of using the ImageList, ImageIndex, and ImageWidth properties

Any component that has the property images (which accepts a TImageList) can use the property ImageWidth to inform the resolution that you want to apply to the selected image since such resolution has been previously added to the ImageList selected.

In this way, we learned that ImageList in Lazarus is a little different from Delphi, having extra features.

Important: ImageList can accept any type of image supported by the IDE and Pascal, however, many programmers don't just use it to put art on buttons, menus, DBGrids, etc... it can also be used to convert from one image to another , enable transparency, use of masks, read/save images from disk and so many other things and avoid programming complexities by using these formats directly.

You must be wondering what is the best graphic format to use within your programs? It depends, if it's just for graphic art on buttons, banners and styles used by your program there's no doubt that the best format is PNG because they keep the same quality in different resolutions. But if you intend to use the images inside reports, PDFs and/or interact with other third-party components maybe the best format is Bitmap, all third-party components that handle images are Bitmap compatible, but not all of them handle PNG and it usually requires you to convert them to Bitmap in order to enjoy it so it's faster not to convert and use Bitmap directly.

If you want to study the examples, they can be obtained here:

https://github.com/gladiston/lazdemos_gsl