Delphi - Populate an imagelist with icons at runtime 'destroys' transparency

回眸只為那壹抹淺笑 提交于 2019-12-09 12:36:24

问题


I've spended hours for this (simple) one and don't find a solution :/

I'm using D7 and the TImageList. The ImageList is assigned to a toolbar. When I populate the ImageList at designtime, the icons (with partial transparency) are looking fine. But I need to populate it at runtime, and when I do this the icons are looking pretty shitty - complete loose of the partial transparency.

I just tried to load the icons from a .res file - with the same result. I've tried third party image lists also without success. I have no clue what I could do :/ Thanks 2 all ;)

edit:

To be honest I dont know exactly whats going on. Alpha blending is the correkt term... Here are 2 screenies:

Icon added at designtime:
(source: shs-it.de)

Icon added at runtime:
(source: shs-it.de)

Your comment that alpha blending is not supported just brought the solution: I've edited the image in an editor and removed the "alpha blended" pixels - and now it looks fine. But its still strange that the icons look other when added at runtime instead of designtime. If you (or somebody else ;) can explain it, I would be happy ;) thanks for you support!


回答1:


To support alpha transparency, you need to create the image list and populate it at runtime:

function AddIconFromResource(ImageList: TImageList; ResID: Integer): Integer;
var
  Icon: TIcon;
begin
  Icon := TIcon.Create;
  try
    Icon.LoadFromResourceID(HInstance, ResID);
    Result := ImageList.AddIcon(Icon);
  finally
    Icon.Free;
  end;
end;

function AddPngFromResource(ImageList: TImageList; ResID: Integer): Integer;
var
  Png: TPngGraphic;
  ResStream: TStream;
  Bitmap: TBitmap;
begin
  ResStream := nil;
  Png := nil;
  Bitmap := nil;
  try
    ResStream := TResourceStream.CreateFromID(HInstance, ResID, RT_RCDATA);
    Png := TPNGGraphic.Create;
    Png.LoadFromStream(ResStream);
    FreeAndNil(ResStream);
    Bitmap := TBitmap.Create;
    Bitmap.Assign(Png);
    FreeAndNil(Png);
    Result := ImageList.Add(Bitmap, nil);              
  finally
    Bitmap.Free;
    ResStream.Free;
    Png.Free;
  end;
end;

// this could be e.g. in the form's or datamodule's OnCreate event
begin
  // create the imagelist
  ImageList := TImageList.Create(Self);
  ImageList.Name := 'ImageList';
  ImageList.DrawingStyle := dsTransparent;
  ImageList.Handle := ImageList_Create(ImageList.Width, ImageList.Height, ILC_COLOR32 or ILC_MASK, 0, ImageList.AllocBy);
  // populate the imagelist with png images from resources
  AddPngFromResource(ImageList, ...);
  // or icons
  AddIconFromResource(ImageList, ...);

end;



回答2:


I had the exact same problems a couple of years ago. It's a Delphi problem. I ended up putting the images in the list at design time, even though I really didn't want to. I also had to use a DevExpress image list to get the best results and to use 32 bit color images.




回答3:


As Jeremy said this is indeed a Delphi limitation.

One work around I've used for images that I was putting onto buttons (PNGs with alpha transparency in my case) is to store the PNGs as resources, and at run time paint them onto a button sized bitmap filled with clBtnFace. The bitmap was then used as the control's glyph.

Delphi's built in support for icons with alpha masks is very limited, however there's an excellent icon library kicon which may help.



来源:https://stackoverflow.com/questions/3056889/delphi-populate-an-imagelist-with-icons-at-runtime-destroys-transparency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!