Sign in Join
Wiki copytemporary

TImageList: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11**TImageList** ![](/wiki-images/c/cc/Timagelist.png) is a component that provides a list of images that can be shared between other components like [[TMainMenu]]/[[TMenuItem]], [[TToolBar]]/[[TToolButton]], [[TActionList]], [[TBitBtn]] or [[TSpeedButton]]. All images have the same size as specified by the `Width` and `Height` property of `TImageList`. A component needing an image specifies this by means of its `ImageIndex` property.
22
33## Multiple-resolution TImageList in Lazarus 1.9 and newer
44
55In Lazarus 1.9 the TImageList was rewritten to support multiple resolutions of one image.
66
7-<figure>
8-<img src="ImageListEd-1.9.png" title="ImageListEd-1.9.png" />
9-<figcaption>ImageListEd-1.9.png</figcaption>
10-</figure>
7+![](/wiki-images/5/5b/ImageListEd-1.9.png)
118
129Every LCL control that supports an `ImageList` has now a new `ImagesWidth` property to decide what custom width at 96 PPI (100% scale) is to be used. Example: TToolBar.Images/ImageWidth, TListView.LargeImages/LargeImagesWidth.
1310
1411Set the `Scaled` property to True and the image list will automatically pick up the scaled image in your High-DPI aware LCL application (provided that the option "Use LCL Scaling" has been checked in the project options).
1512
1613### Demo applications
1714
1815There are 2 demo applications in Lazarus sources:
1916
2017- examples/imagelist_highdpi_designtime
2118- examples/imagelist_highdpi_runtime
2219
2320### Changes affecting backwards compatibility
2421
2522#### Add method
2623
2724- Old behavior: the image got sliced if too big or extended if too small.
2825- New behavior: the image is scaled to all resolutions in the image list.
2926- Reason: Image List now supports multiple resolutions.
3027- Remedy: use AddSliced (if the image consists of several icons to be added) or AddSlice (if one image from a custom rect has to be added - also rect outside the image is supported).
3128
3229### How to create a multi-resolution ImageList in the application
3330
3431- In the first step you must tell the Imagelist which image sizes are needed.
3532 - Decide on the basic image size, usually 16x16. This is used at 96ppi screen resolution (in Windows: 100%).
3633 - If your application will also run at 144ppi (150%) or 192ppi (200%), it will also need images at 24x24 and 32x32 (24 = 150% of 16, 32 = 200% of 16).
3734 - In the case that some controls require a larger image size at 96pp, say 32x32, you should also prepare the imagelist for these scaled sizes, i.e. size 48 (=150% of 32) and 64 (=200% of 32) in this example.
3835- Click on the **New resolutions** button and specify each of these extra sizes (only the width must be entered). The 16x16 size does not need to be added by the **New resolutions** button because it is already known from the `Imagelist.Width` and `.Height` properties.
3936
4037- In the next step you add the images themselves.
4138 - Click on the **Add more resolutions** button.
4239 - Navigate to the folder in which your images are stored (The png image format is highly recommended). Lazarus 2.3+, for example, has the *images/general_purpose* folder in its installation directory which is full of free png images designed for typical applications (thanks to Roland Hahn...). (svg master files can be found at <https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/image_sources/lazarus/images/general_purpose/>).
4340 - Multi-select all sizes of the image that you want to load.
4441 - *OK* loads the images into the image list editor; missing sizes will be scaled down from larger sizes in surprisingly good quality.
4542 - Repeat with the other motives that you need.
4643 - Add only images that you need - they require a fairly large amount of memory.
4744 - If you wonder about the difference between the **Add** and **Add more resolutions** buttons: When you click **Add** only a single image can be selected, and the other sizes are extrapolated from it. **Add more resolutions**, on the other hand, allows multi-selection so that the individual images of the specific size can be selected.
4845 - The **Replace** and **Replace all resolutions** buttons allow to replace the image selected in the imagelist editor by another motif.
4946 - **Delete** removes all sizes of the image selected in the imagelist.
5047 - **Clear** erases the entire imagelist.
5148
5249- If you draw the images yourself, you may skip all the intermediate sizes. The minimum is to draw the largest images that you need; the smaller ones are scaled down automatically upon loading. However, the smallest image (16x16), sometimes also 24x24, appears a bit fuzzy; therefore, it is recommended to provide special versions of these sizes as well. It is maybe a good idea to draw the images in vector format (svg, using Inkscape) and to export to the needed size in png format.
5350
5451- Finally select the controls which require the non-standard default size and set their `ImagesWidth` to the corresponding value. In case of a `TListView` having a `SmallImages` and a `LargeImages` property, for example, set the `LargeImagesWidth` to 32; the `SmallImagesWidth` can stay at its default value, 0, because it is interpreted as the default size defined by the `Imagelist.Width`.
55-- In order to activate automatic scaling of image sizes according to the current resolution of the monitor you must set the <b>`Scaled`</b> property of the Imagelist to `true`. Usually you should also provide a handler for the Imagelist event <b>`OnGetWidthForPPI`</b> to define that images should be scaled also for intermediate resolutions which were not added explictly in the "New resolutions" step above. (Otherwise only the next-smaller predefined image sizes will be used).
52+- In order to activate automatic scaling of image sizes according to the current resolution of the monitor you must set the `Scaled` property of the Imagelist to `true`. Usually you should also provide a handler for the Imagelist event `OnGetWidthForPPI` to define that images should be scaled also for intermediate resolutions which were not added explictly in the "New resolutions" step above. (Otherwise only the next-smaller predefined image sizes will be used).
5653
5754``` Pascal
5855procedure TForm1.ImageList1GetWidthForPPI(Sender: TCustomImageList;
5956 AImageWidth, APPI: Integer; var AResultWidth: Integer);
6057begin
6158 AResultWidth := AImageWidth * APPI div 96;
6259end;
6360```
6461
6562## High-DPI alternative for Lazarus 1.8 and older: resize all images in TImageList
6663
6764This is useful for example for [[High DPI]] scaling to get icons with higher resolution for TActionList, TMainMenu and TToolBar. Note: This may not work correctly with all widgetsets on all platforms. Note also: This code is not required for Laz 1.9+.
6865
6966``` pascal
7067procedure ScaleImageList(ImgList: TImageList; NewWidth, NewHeight: Integer);
7168var
7269 TempImgList: TImageList;
7370 TempBmp1: TBitmap;
7471 TempBmp2: TBitmap;
7572 I: Integer;
7673begin
7774 TempImgList := TImageList.Create(nil);
7875 TempBmp1 := TBitmap.Create;
7976 TempBmp1.PixelFormat := pf32bit;
8077 TempBmp2 := TBitmap.Create;
8178 TempBmp2.PixelFormat := pf32bit;
8279 TempBmp2.SetSize(NewWidth, NewHeight);
8380 try
8481 TempImgList.Width := NewWidth;
8582 TempImgList.Height := NewHeight;
8683
8784 for I := 0 to ImgList.Count - 1 do begin
8885 // Load image for given index to temporary bitmap
8986 ImgList.GetBitmap(I, TempBmp1);
9087
9188 // Clear transparent image background
9289 TempBmp2.Canvas.Brush.Style := bsSolid;
9390 TempBmp2.Canvas.Brush.Color := TempBmp2.TransparentColor;
9491 TempBmp2.Canvas.FillRect(0, 0, TempBmp2.Width, TempBmp2.Height);
9592
9693 // Stretch image to new size
9794 TempBmp2.Canvas.StretchDraw(Rect(0, 0, TempBmp2.Width, TempBmp2.Height), TempBmp1);
9895 TempImgList.Add(TempBmp2, nil);
9996 end;
10097
10198 ImgList.Assign(TempImgList);
10299 finally
103100 TempImgList.Free;
104101 TempBmp1.Free;
105102 TempBmp2.Free;
106103 end;
107104end;
108105```
109106
110107## Example with ComboBox
111108
112109To use TImageList, drop an TImageList object onto the form. In this example we need six images.
113110
114111All images must be the same size. If two sizes of image are to be used, then two TImageLists must be used.
115112
116113Set the height and width of the images in the Object Inspector; In this case 50px wide by 18px high.
117114
118115Set Style to csOwnerDrawFixed.
119116
120117Double-click on the TImageList icon to open the TImageList editor. Make sure that the icons show correctly when selected. If they are smaller than expected, check the size in the Object Inspector \<F11\>. You may have to reload the images.
121118
122-<figure>
123-<img src="ImageListEd.png" title="ImageListEd.png" />
124-<figcaption>ImageListEd.png</figcaption>
125-</figure>
119+![](/wiki-images/1/13/ImageListEd.png)
126120
127121Place a ComboBox on the form and name it cbSymbols.
128122
129123In the FormCreate event enter:
130124
131125``` pascal
132126 cbSymbols.Items.Clear;
133127 for I := 0 to 5 do
134128 cbSymbols.Items.Add('');
135129 cbSymbols.ItemIndex := 0;
136130```
137131
138132This will write 6 blank entries, and select the first.
139133
140134In the OnDrawItem event for cbSymbols place the following code:
141135
142136``` pascal
143137procedure TMyForm.cbSymbolsDrawItem(
144138 aControl: TWinControl;
145139 iIndex: Integer;
146140 aRect: TRect;
147141 aState: TOwnerDrawState );
148142var
149143 cnv: TCanvas;
150144begin
151145 if not (aControl is TComboBox) then exit;
152146 cnv := TComboBox( aControl ).Canvas;
153147 Imagelist1.Draw( cnv, aRect.Left+2, aRect.Top+2, iIndex );
154148end;
155149```
156150
157151The adjustments (+2) are to center the image in the item, if necessary.
158152
159-<figure>
160-<img src="combo.png" title="combo.png" />
161-<figcaption>combo.png</figcaption>
162-</figure>
153+![](/wiki-images/1/1a/Combo.png)
163154
164155## Example with SpeedButton
165156
166157Add images to the ImageList1 like in the previous example and use:
167158
168159``` pascal
169160 ImageList1.GetBitmap(iIndex,SpeedButton1.Glyph);
170161```
171162
172163## See also
173164
174165- [[doc:lcl//controls/timagelist.html|TImageList doc]]
175166- [[TImage]]
176167
177168---
178169*From the Free Pascal wiki, page "TImageList", as it stood on 2023-12-22 after a change by Wp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history