I recently came across a situation where I needed to write a counter to an image used for a navbar, where the image was coming from an imagelist component.
After racking my brain for a few hours looking at other articles such as:
How to load a transparent Image from ImageList?
*.bmp loses transparent background if using v6 ImageList Control
http://codeverge.com/embarcadero.delphi.graphics/timage-is-not-transparent-after-a/1080826
http://www.efg2.com/Lab/Library/Delphi/Graphics/ICOtoBMP.pas.txt
I settled on a solution that copied the bitmap from the imagelist, wrote the text to the bitmap canvas, then put the bitmap back into the imagelist.
The only problem with this was that I lost the transparency, and for the life of me couldn't figure out how to get it back.
I could extract and reassign the image OK, including transparency, if I used GetIcon instead of GetBitmap, but then I didn't have a Canvas in order to use TextOut.
If I set the colour so that the image looks correct in components that are linked to the imagelist, like my navbar, when you extract the image using GetBitmap, the transparency is lost and it looks white when applied directly to a TImage.
OK. No problem. Just use white as the transparency colour...
Nope. Even though Canvas.Pixels[0, 31]
showed 16777215 as the colour, which is the same value as clWhite, using that for the TransparentColour had no effect.
To see what I mean, create a new VCL Forms Application in Delphi, drop on a couple of TButtons and a TImageList, and link the second button to the image list by setting the buttons Images property in the designer. Double-click the first button and set the event code to be this:
procedure TForm1.Button1Click(Sender: TObject);
var
Bitmap : TBitMap;
begin
Bitmap := TBitmap.Create;
try
ImageList1.GetBitmap(0, BitMap);
BitMap.Canvas.Brush.Style := bsClear;
BitMap.Canvas.Font.Size := 10;
BitMap.Canvas.Font.Color := clBlack;
BitMap.Canvas.Font.Style := [fsBold];
BitMap.Canvas.TextOut(8, 0, '100');
Bitmap.Transparent := True;
Bitmap.TransParentColor := Bitmap.Canvas.Pixels[0, 31]; // Bottom left
ImageList1.ReplaceMasked(0, BitMap, Bitmap.TransParentColor);
finally
Bitmap.Free;
end;
end;
Now add a non-transparent bitmap to the image list (change the size according to how you want it. I use 32x32 pixel bitmaps). By default the component shows the Transparent Colour as being whatever the bottom left pixel is. Leave this as is and OK the imagelist change. Change the ImageIndex of the second button to 0.
You should now see the bitmap you added to the image list shown on the second button, with whatever was the transparent colour being, well, transparent.
Now click the first button. The image on the second button changes to have "100" being shown, but whatever was transparent is now white.