1. 程式人生 > >Delphi中GDI+和ImageList使用的正確姿勢

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;