Delphi 以灰度绘制来自TPngImageList的位图图像

Delphi 以灰度绘制来自TPngImageList的位图图像,delphi,timagelist,Delphi,Timagelist,TImageList允许您使用False作为最后一个参数,在禁用状态下将其中一个图像绘制到位图 ImageList.Draw(DestBitmap.Canvas, 0, 0, ImageIndex, False); 我想这样做,也灰度目标位图 我有以下代码: procedure ConvertBitmapToGrayscale(const Bitmap: TBitmap); type PPixelRec = ^TPixelRec; TPixelRec = packed record

TImageList
允许您使用
False
作为最后一个参数,在禁用状态下将其中一个图像绘制到位图

ImageList.Draw(DestBitmap.Canvas, 0, 0, ImageIndex, False);
我想这样做,也灰度目标位图

我有以下代码:

procedure ConvertBitmapToGrayscale(const Bitmap: TBitmap);
type
  PPixelRec = ^TPixelRec;
  TPixelRec = packed record
    B: Byte;
    G: Byte;
    R: Byte;
    Reserved: Byte;
  end;
var
  X: Integer;
  Y: Integer;
  P: PPixelRec;
  Gray: Byte;
begin
  Assert(Bitmap.PixelFormat = pf32Bit);
  for Y := 0 to (Bitmap.Height - 1) do
  begin
    P := Bitmap.ScanLine[Y];
    for X := 0 to (Bitmap.Width - 1) do
    begin
      Gray := Round(0.30 * P.R + 0.59 * P.G + 0.11 * P.B);
      P.R := Gray;
      P.G := Gray;
      P.B := Gray;
      Inc(P);
    end;
  end;
end;

procedure DrawIconShadowPng(ACanvas: TCanvas; const ARect: TRect; ImageList:
    TCustomImageList; ImageIndex: Integer);
var
  ImageWidth, ImageHeight: Integer;
  GrayBitMap : TBitmap;
begin
  ImageWidth := ARect.Right - ARect.Left;
  ImageHeight := ARect.Bottom - ARect.Top;
  with ImageList do
  begin
    if Width < ImageWidth then ImageWidth := Width;
    if Height < ImageHeight then ImageHeight :=  Height;
  end;

  GrayBitMap := TBitmap.Create;
  try
    GrayBitmap.PixelFormat := pf32bit;
    GrayBitMap.SetSize(ImageWidth, ImageHeight);

    ImageList.Draw(GrayBitMap.Canvas, 0, 0, ImageIndex, False);
    ConvertBitmapToGrayscale(GrayBitMap);

    BitBlt(ACanvas.Handle, ARect.Left, ARect.Top, ImageWidth, ImageHeight,
      GrayBitMap.Canvas.Handle, 0, 0, SRCCOPY);
  finally
    GrayBitMap.Free;
  end;
end;
procedure ConvertBitmapToGrayscale(常量位图:TBitmap);
类型
PPixelRec=^TPixelRec;
TPixelRec=打包记录
B:字节;
G:字节;
R:字节;
保留:字节;
结束;
变量
X:整数;
Y:整数;
P:PPixelRec;
灰色:字节;
开始
断言(Bitmap.PixelFormat=pf32位);
对于Y:=0到(Bitmap.Height-1)do
开始
P:=位图.扫描线[Y];
对于X:=0到(Bitmap.Width-1)do
开始
灰色:=圆形(0.30*P.R+0.59*P.G+0.11*P.B);
P.R:=灰色;
P.G:=灰色;
P.B:=灰色;
公司(P),;
结束;
结束;
结束;
程序图纸(ACanvas:TCanvas;const ARect:TRect;图像列表:
TCustomImageList;ImageIndex:Integer);
变量
ImageWidth、ImageHeight:整数;
灰度位图:TBitmap;
开始
ImageWidth:=ARect.Right—ARect.Left;
ImageHeight:=ARect.Bottom-ARect.Top;
用ImageList做什么
开始
如果宽度<图像宽度,则图像宽度:=宽度;
如果高度<图像高度,则图像高度:=高度;
结束;
灰度位图:=TBitmap.Create;
尝试
GrayBitmap.PixelFormat:=PF32位;
设置大小(图像宽度、图像高度);
ImageList.Draw(GrayBitMap.Canvas,0,0,ImageIndex,False);
ConvertBitmapToGrayscale(灰度位图);
BitBlt(ACanvas.Handle、ARect.Left、ARect.Top、ImageWidth、ImageHeight、,
GrayBitMap.Canvas.Handle,0,0,SRCCOPY);
最后
灰色位图。免费;
结束;
结束;
问题是生成的图像有白色背景

如何使背景透明


我正在使用TPngImageList,因为它比常规的TImageList更好地处理Png图像。(在XE4中)

您也可以对
TPngImageList
使用
Draw
方法。要获得灰度图像,您必须首先在其
PngOptions
属性中使用
pnggrayscaleonpabled
选项启用该选项。

谢谢,我不知道该选项。如果有帮助的话,我仍然有兴趣知道如何“手动”实现我试图实现的功能,
PngFunctions.pas
有一个过程
MakeImageGrayscale
,但它在PNG而不是BMP上工作。您需要获取原始位图,包括其alpha通道。您当前在位图上绘制并丢失alpha。