Recent

Author Topic: Cannot add transparent bitmap to TImageList  (Read 9838 times)

ned_flanders

  • New Member
  • *
  • Posts: 26
Cannot add transparent bitmap to TImageList
« on: September 15, 2013, 12:44:10 pm »
Running Lazarus v1.0.12 under Win32, I am trying to add a Bitmap to a TImageList but I cannot get it transparent.

First I create a new bitmap using:

Code: [Select]
procedure FillBitmapCanvas(Bitmap: TBitmap; CanvasHeight, CanvasWidth: Integer;
  CanvasColor, FrameColor: TColor; FrameSize: Integer);
begin
  with Bitmap do
  begin
    Height := CanvasHeight;
    Width := CanvasWidth;
    Canvas.Brush.Color := CanvasColor;
    Canvas.Pen.Color := FrameColor;
    Canvas.Pen.Width := FrameSize;
    Canvas.Rectangle(Rect(0, 0, Bitmap.Width, Bitmap.Height));
  end;
end;

Then I add it to the Imagelist like so:

Code: [Select]
procedure AddToImageList(ImageList: TImageList); 
var
  _TransColor: TColor;
  Bitmap: TBitmap;
begin
  _TransColor := clFuchsia;

  Bitmap := TBitmap.Create;
  try
    Bitmap.Transparent := True;
    Bitmap.TransparentMode := tmFixed;
    Bitmap.TransparentColor := _TransColor;
    FillBitmapCanvas(Bitmap, ImageList.Height, ImageList.Width, _TransColor, _TransColor, 0);
    ImageList.AddMasked(Bitmap, _TransColor);
  finally
    Bitmap.Free;
  end;
end; 

When I assign this image to a node in a Treeview it shows as solid pink square, when really I should not see it at all (unless it has other non fuchsia pixels on it).

What do I need to change to get it working?

Thanks.

tfk

  • New member
  • *
  • Posts: 8
Re: Cannot add transparent bitmap to TImageList
« Reply #1 on: September 15, 2013, 02:17:21 pm »
Howdy,

Code looks all right. What happens when you set the pixelformat of the Bitmap to something higher than 8bpp?

For instance:
Bitmap.PixelFormat := pf32bit;

Also you could try setting the bitmap properties after drawing.

TFK
« Last Edit: September 15, 2013, 02:32:41 pm by tfk »

ned_flanders

  • New Member
  • *
  • Posts: 26
Re: Cannot add transparent bitmap to TImageList
« Reply #2 on: September 15, 2013, 03:22:39 pm »
Hi, thanks for the reply  :)

I tried changing it to both 24-bit and 32-bit, and moved the transparency part after calling FillBitmapCanvas, I just get a black square now.

I wonder if this is a lazarus bug, it should not be so trivial to add a transparent bitmap to a imagelist..

tfk

  • New member
  • *
  • Posts: 8
Re: Cannot add transparent bitmap to TImageList
« Reply #3 on: September 15, 2013, 04:52:25 pm »
I think I've got it. With an image that has both a transparent color and a color that should be shown...

An image fully filled with a transparent color stil displays opaque. But that is also the case in the property editor of the imagelist.

This is what I have:

Imagelist properties in property editor:
  BkColor: clFuchsia
  DrawingStyle: dsTransparent
  ImageType: itImage
  Masked: False

And in code:
Code: [Select]
...
  _TransColor := clFuchsia;

  Bitmap := TBitmap.Create;
  try
    Bitmap.PixelFormat := pf16bit; // 16bits only...

    FillBitmapCanvas(Bitmap, ImageList.Height, ImageList.Width, _TransColor,
    _TransColor, 1);
    //Bitmap.PixelFormat := pf16bit; // don't set this value here, your image will be black...
    //Bitmap.Transparent := True;
    //Bitmap.TransparentMode := tmAuto;
    //Bitmap.TransparentColor := _TransColor;

    ImageList.AddMasked(Bitmap, _TransColor);

  finally
    Bitmap.Free;
  end;
...

procedure FillBitmapCanvas(Bitmap: TBitmap; CanvasHeight,
  CanvasWidth: Integer; CanvasColor, FrameColor: TColor; FrameSize: Integer);
begin
  with Bitmap do
  begin
    Height := CanvasHeight;
    Width := CanvasWidth;
    Canvas.Brush.Color := CanvasColor;
    Canvas.Pen.Color := clLime;
    Canvas.Pen.Width := FrameSize;

    Canvas.FillRect(0, 0, Bitmap.Width, Bitmap.Height);

    Canvas.Brush.Color := clLime;
    Canvas.FillRect(4, 4, Bitmap.Width-4, Bitmap.Height-4);
  end;
end;




I've been testing with an actual image (attached) and the property editor. There I see some confirmation on what rules apply here:

  • It only works with images saved in 16bit colors;
  • When you add the image it looks transparent, which is good. But when you set the transparent color of the image added to the color chosen as background color in the imagelist it goes opaque.
  • An image that is completely filled with the transparent color will not be transparent.

I assume that there is some correlation between the transparency settings set on the image itself and those set on the imagelist. It seems that in this case it's best to just "draw" and "add" and let the imagelist do the rest.

TFK
« Last Edit: September 15, 2013, 05:13:52 pm by tfk »

ned_flanders

  • New Member
  • *
  • Posts: 26
Re: Cannot add transparent bitmap to TImageList
« Reply #4 on: September 15, 2013, 05:24:38 pm »
Interesting find  :)

I will have a look at this some more when I get the time.

Thanks  8)

ned_flanders

  • New Member
  • *
  • Posts: 26
Re: Cannot add transparent bitmap to TImageList
« Reply #5 on: September 17, 2013, 09:00:40 pm »
Yup you were right,

In the Imagelist editor at designtime I tried adding a png image that was fully transparent, as soon as I added it was solid in color. I went back and edited my blank transparent png (in paint.net) and included one tiny pixel that was a different color to the transparent one, and what do you know it added as transparent.

That is good, but I need a fully transparent image adding to the list  %)

Does anyone have a workaround?

tfk

  • New member
  • *
  • Posts: 8
Re: Cannot add transparent bitmap to TImageList
« Reply #6 on: September 17, 2013, 10:59:08 pm »
Maybe on creation or activation of the form going through all images in the list and paint one pixel in the color clDefault?

Theoretically it should appear as transparent on all systems...  :-\

Not tested but you could try...  ;D

TFK

ned_flanders

  • New Member
  • *
  • Posts: 26
Re: Cannot add transparent bitmap to TImageList
« Reply #7 on: September 18, 2013, 12:47:59 am »
Good suggestion, I will give that a try.

What I did for now was in Paint.Net I set the opacity of the background to 1 (not fully transparent) and added a pixel (which is barely noticeable), and saved as png. The imagelist adds it and looks full transparent this way, but ideally a runtime or more practical solution is needed.

I will try your suggestion a bit later..  8)

 

TinyPortal © 2005-2018