delphidelphi-5timagelist

How to load a bitmap, with background color, into a TImageList in Delphi 5?


Short Version

Fill in the fuction:

procedure LoadImageListMasked(AImageList: TImageList; hbmp: HBITMAP; TransparentColor: TColor);
var
   bmp: Graphics.TBitmap;
begin
   bmp := Graphics.TBitmap.Create;
   bmp.Handle := hbmp;
   bmp.Transparent := True;
   bmp.TransparentMode := tmFixed;
   bmp.TransparentColor := TransparentColor;
   AImageList.AddMasked(bmp, TransparentColor);
   bmp.Free;
end;

Long Version

I have a handle (hbmp) to a 256-color bitmap:

enter image description here

I want to load this image in a (Delphi 5) TImageList, using the clFuchsia as the mask color:

var
   bmp: TGraphics.TBitmap;

   bmp := TBitmap.Create;
   bmp.Transparent := True;           //Default: False
   bmp.TransparentMode  := tmFixed;   //Default: tmAuto
   bmp.TransparentColor := clFuchsia; //Default: $02FF00FF
   bmp.Handle := hbmp;

   ImageList1.Clear;
   ImageList1.Height := bmp.Height;
   ImageList1.Width := bmp.Height;
   ImageList1.BkColor := clNone;      //Default: $1FFFFFFF (clNone)
   ImageList1.AddMasked(bmp, clFuchsia);

Except when I actually use the images in the image list (on a TToolbar say), the clFuchsia color isn't masked off:

enter image description here

What am i doing wrong?

Options Grid

There are various options available to be played with:

Lets try every combination i can think of:

TransparentMode TransparentColor BkColor Result
tmAuto (default) -1 (default) clFuchsia Fail
tmAuto (default) -1 (default) clNone (default) Fail
tmFixed clFuchsia clNone (default) Fail
tmAuto (default) -1 (default) clNone (default) then assign the handle:
tmAuto (default) $02FF00FF (auto) clNone (default) Fail
tmAuto (default) -1 (default) clNone (default) then assign the handle:
tmAuto (default) $02FF00FF (auto) clNone (default) then change Mode to tmFixed:
tmFixed $02FF00FF (auto) clNone (default) Fail
tmAuto (default) -1 (default) clNone (default) then assign the handle:
tmAuto (default) $02FF00FF (auto) clNone (default) then change mode to tmFixed:
tmFixed $02FF00FF (auto) clNone (default) then change TransparentColor to clFuchsia:
tmFixed $02FF00FF (clFuchsia) clNone (default) Fail

After tracing through the VCL i realized there is another property of TBitmap:

TBitmap.Transparent: Boolean

It defaults to False. I've now also tried setting it to True.


Solution

  • Don't set the TImageList.BkColor, leave it at its default of clNone. You are telling the TImageList to draw its masked bitmaps onto the TToolbar over a fixed color. That is why your TToolBar is showing fuchsia. It is the TImageList.BkColor being shown, not the TBitmap.TransparentColor.


    Also, just as an FYI...

    Don't set the TBitmap.TransparentMode property to tmAuto if you want a specific TransparentColor.

    Setting the TransparentColor property to a value other than clDefault will set the TransparentMode property to tmFixed. Then setting the TransparentMode back to tmAuto will set the TransparentColor back to crDefault, thus losing your color choice.

    Though, it shouldn't really matter, as internally AddMasked() creates a new TBitmap copied from the source TBitmap, and it will set the copied bitmap's TransparentColor to the input TColor you specify, so you don't actually need to make your source TBitmap be transparent at all.