Delphi中GDI+和ImageList使用的正確姿勢
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;