4
votes

How do I take a picture from a TImageList and put it into a TImage (or return it as a TGraphic)?

The important point is that a TImageList can contain 32-bpp alpha blended images. The goal is to get one of these alpha-blended images and place it in a TImage. This means at some point i would likely require a TGraphic. Although, strictly speaking, my question is about placing an image from an ImageList into an Image. If that can be accomplished without an intermedate TGraphic then that is also fine.

What do we want?

We want the guts of a function:

procedure GetImageListImageIntoImage(SourceImageList: TCustomImageList; 
      ImageIndex: Integer; TargetImage: TImage);
begin
   //TODO: Figure this out.
   //Neither SourceImageList.GetIcon nor SourceImageList.GetBitmap preserve the alpha channel
end;

There can also be another useful intermediate helper function:

function ImageListGetGraphic(ImageList: TCustomImageList; ImageIndex: Integer): TGraphic;
var
//  ico: TIcon;
    bmp: TBitmap;
begin
    {Doesn't work; loses alpha channel. 
    Windows Icon format can support 32bpp alpha bitmaps. But it just doesn't work here
    ico := TIcon.Create;
    ImageList.GetIcon(ImageIndex, ico, dsTransparent, itImage);
    Result := ico;
    }

    {Doesn't work; loses alpha channel.
    Windows does support 32bpp alpha bitmaps. But it just doesn't work here
    bmp := TBitmap.Create;
    bmp.PixelFormat := pf32bit;
    Imagelist.GetBitmap(ImageIndex, bmp);
    Result := bmp;
    }
end;

Letting us convert the original procedure to:

procedure GetImageListImageIntoImage(SourceImageList: TCustomImageList; ImageIndex: Integer; TargetImage: TImage);
var
   g: TGraphic;
begin
   g := ImageListGetGraphic(SourceImageList, ImageIndex);
   TargetImage.Picture.Graphic := g; //Assignment of TGraphic does a copy
   g.Free;
end;

I also some random things:

Image1.Picture := TPicture(ImageList1.Components[0]);

but that does not compile.

P.S. I have Delphi 2010

2
"I get a runtime error" means nothing unless you tell us what error, including the exact error message and any memory addresses.Ken White
@Ken - I bet it's a compile time error since there's no 'Pictures' property for a TImage, and even if it was 'Picture' that code wouldn't compile (picture <> component).Sertac Akyuz
@Sertac, I agree. It would help, though, if the question contained the info. People seem to forget that we can't see their screens from where we sit. (At least I can't, and psychic debugging should be a last resort. <g>)Ken White

2 Answers

3
votes
ImageList1.GetBitmap(0, Image1.Picture.Bitmap);
1
votes

Routine to get a transparent graphic out of an ImageList:

function ImageListGetGraphic(ImageList: TCustomImageList; ImageIndex: Integer): TGraphic;
var
    ico: HICON;
//  png: TPngImage;
//  icon: TIcon;
//  bmp: TBitmap;
    wicbmp: IWICBitmap;
    wi: TWicImage;
begin
{   //Works. Uses our own better Wic library.
    ico := ImageList_GetIcon(ImageList.Handle, ImageIndex, ILD_NORMAL);
    Result := TWicGraphic.FromHICON(ico);
    DestroyIcon(ico);}

    //Works, uses the built-in Delphi TWicImage (careful of VCL bugs)
    ico := ImageList_GetIcon(ImageList.Handle, ImageIndex, ILD_NORMAL);
    wi := TWICImage.Create; //Due to a bug in the VCL, you must construct the TWicImage before trying to access the Wic ImagingFactory
    OleCheck(TWicImage.ImagingFactory.CreateBitmapFromHICON(ico, wicbmp));
    wi.Handle := wicbmp;
    Result := wi;

{   //Doesn't work, loses alpha channel
    icon := TIcon.Create;
    ImageList.GetIcon(ImageIndex, icon, dsTransparent, itImage);
    Result := icon;
    }

{   //Doesn't work, loses alpha channel
    bmp := TBitmap.Create;
    bmp.PixelFormat := pf32bit;
    Imagelist.GetBitmap(ImageIndex, bmp);
    Result := bmp;
    }

{   //Fails: cannot assign a TIcon to a TPngImage
    icon := TIcon.Create;
    ImageList.GetIcon(ImageIndex, icon, ImgList.dsNormal, itImage);
    png := TPngImage.Create;
    png.Assign(icon);
    Result := png;
    icon.Free;
    }

{   //Working failure; doesn't support stretched drawing (e.g. TImage.Stretch = true)
    icon := TIcon.Create;
    ImageList.GetIcon(ImageIndex, icon, ImgList.dsNormal, itImage);
    Result := ico;
    }

end;

Sample usage:

g: TGraphic;

g := ImageListGetGraphic(ImageList1, 7);
Image1.Picture.Graphic := g;
g.Free;

Note: Any code released into public domain. No attribution required.