PNG image from imagelist
Asked Answered
I

2

4

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

Incubate answered 10/6, 2012 at 22:51 Comment(3)
"I get a runtime error" means nothing unless you tell us what error, including the exact error message and any memory addresses.Activator
@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).Perpetrate
@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>)Activator
M
2
ImageList1.GetBitmap(0, Image1.Picture.Bitmap);
Maidservant answered 10/6, 2012 at 22:59 Comment(9)
@Giacomo - What's the problem, transparency is lost?Perpetrate
TImageList only supports ICO and BMP formats. Putting a PNG into a TImageList converts it to a BMP. If you want to preserve a PNG as a PNG, you have to use another component that supports that, such as a TPngImageList.Transudate
Add your PNG to a resource... then load it from the resource... #1153894Masturbation
@GiacomoKingPatermo for 32 bits png images, you can use the GetIcon method to extract the image and preserve the transparency , so try ImageList1.GetIcon(0, Image1.Picture.Icon);Storebought
@Giacomo - Nobody knows the problem until you tell it. How does "it doesn't work"? Are you getting an error?Perpetrate
Error: List index out of bounds (0)Incubate
@Giacomo - It looks like it is raised from somewhere else in your code. You're probably using a list, listbox etc.. and have an error with it.Perpetrate
@GiacomoKingPatermo how many images are contained inside ImageList1?Maidservant
@GiacomoKingPatermo can you add your .png image to your question?Maidservant
W
0

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.

Walls answered 14/10, 2014 at 17:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.