GDI+DrawImage只能传入TGPImage, 因此最初想到的是从ImageList中得到Image, 然后存储为流,再转换为TGPImage,然后显示。
function drawImageList(graphics: TGPGraphics;
paraImageList: TImageList; paraIndex: Itneger; paraRect: TGPRectF)
var
l_gpImage: TGPImage;
l_icon: TIcon;
l_bitmap: TBitmap;
l_memStream: TMemoryStream;
stream: TStreamAdapter;
begin
l_icon:= TIcon.Create;
l_bitmap:= TBitmap.Create;
l_bitmap.PixelFormat := pf32bit;
l_bitmap.AlphaFormat := afDefined;
l_memStream:= TMemoryStream.Create;
try
paraImageList.GetIcon(paraIndex, l_icon);
paraImageList.DrawingStyle:= dsTransparent;
paraImageList.GetBitmap(paraIndex, l_bitmap);
l_rect.X:= paraRect.X + (paraRect.Width - l_rect.Width) / 2;
l_rect.Y:= paraRect.Y + (paraRect.Height - l_rect.Height) / 2 ;
//l_icon.SaveToStream(l_memStream);
l_bitmap.SaveToStream(l_memStream);
l_memStream.Position:= 0;
stream:= TStreamAdapter.Create(l_memStream);
l_gpImage:= TGPImage.Create(stream);
graphics.DrawImage(l_gpImage, l_rect);
end;
问题来了,这样画出的图片不是透明背景的。
如果要画透明背景 可以是用ImageList.GetIcon.
但这种方法的问题是,画出来的图,是模糊的。
另一种方式是不适用Gpgraphics, 而是直接用ImageList.Draw在画布上化。但和GDI+的方式不同一。
最终使用Windows的方法利用GPGraphics.hdc 相对完美实现。
procedure DrawImageListImage(graphics: TGPGraphics;
paraImageList: TcxImageList; paraIndex: Integer; paraRect: TGPRectF);
var
dc: HDC;
X, Y: integer;
begin
if (paraIndex >= 0) and (paraIndex < paraImageList.Count) then
begin
dc:= graphics.GetHDC;
try
X:= round(paraRect.x +(paraRect.Width - paraImageList.Width)/2);
Y:= round(paraRect.Y +(paraRect.Height - paraImageList.Height)/2);
ImageList_DrawEx(paraImageList.Handle, paraIndex, dc,
X, Y, paraImageList.Width, paraImageList.Height,
CLR_NONE, CLR_DEFAULT,
ILD_TRANSPARENT);
finally
end;
end;