Delphi 如何将动态文本写入导航栏使用的TImageList中的图像?

Delphi 如何将动态文本写入导航栏使用的TImageList中的图像?,delphi,transparency,delphi-10.2-tokyo,timagelist,textout,Delphi,Transparency,Delphi 10.2 Tokyo,Timagelist,Textout,我最近遇到一种情况,我需要为导航栏使用的图像编写一个计数器,该图像来自imagelist组件 我绞尽脑汁看了几个小时其他文章,比如: 我找到了一个解决方案,从imagelist复制位图,将文本写入位图画布,然后将位图放回imagelist 唯一的问题是,我失去了透明度,我一辈子都不知道如何找回它 如果我使用GetIcon而不是GetBitmap,我可以提取并重新分配图像OK,包括透明度,但是我没有画布来使用TextOut 如果我设置了颜色,以便在使用GetBitmap提取图像时,图像在链

我最近遇到一种情况,我需要为导航栏使用的图像编写一个计数器,该图像来自imagelist组件

我绞尽脑汁看了几个小时其他文章,比如:

我找到了一个解决方案,从imagelist复制位图,将文本写入位图画布,然后将位图放回imagelist

唯一的问题是,我失去了透明度,我一辈子都不知道如何找回它

如果我使用GetIcon而不是GetBitmap,我可以提取并重新分配图像OK,包括透明度,但是我没有画布来使用TextOut

如果我设置了颜色,以便在使用GetBitmap提取图像时,图像在链接到imagelist的组件(如我的导航栏)中看起来正确,则透明度将丢失,并且直接应用于图像时,它看起来是白色的

嗯。没问题。只需使用白色作为透明度颜色

没有。尽管
Canvas.Pixels[0,31]
显示16777215作为颜色,这与clWhite的值相同,但将其用于透明色没有效果

要了解我的意思,请在Delphi中创建一个新的VCL表单应用程序,放置几个TButtons和一个TImageList,并通过在设计器中设置buttons Images属性将第二个按钮链接到图像列表。双击第一个按钮并将事件代码设置为:

procedure TForm1.Button1Click(Sender: TObject);
var
  Bitmap : TBitMap;
begin
  Bitmap := TBitmap.Create;
  try
    ImageList1.GetBitmap(0, BitMap);
    BitMap.Canvas.Brush.Style := bsClear;
    BitMap.Canvas.Font.Size := 10;
    BitMap.Canvas.Font.Color := clBlack;
    BitMap.Canvas.Font.Style := [fsBold];
    BitMap.Canvas.TextOut(8, 0, '100');
    Bitmap.Transparent := True;
    Bitmap.TransParentColor := Bitmap.Canvas.Pixels[0, 31]; // Bottom left
    ImageList1.ReplaceMasked(0, BitMap, Bitmap.TransParentColor);
  finally
    Bitmap.Free;
  end;
end;
现在将一个不透明位图添加到图像列表中(根据需要更改大小。我使用32x32像素位图)。默认情况下,组件将透明颜色显示为左下角像素的任何颜色。保持原样,然后确定imagelist更改。将第二个按钮的ImageIndex更改为0

您现在应该可以看到添加到第二个按钮上显示的图像列表中的位图,透明颜色是透明的


现在单击第一个按钮。第二个按钮上的图像更改为显示“100”,但透明的图像现在为白色。

解决方案是在添加图像时更改TImageList UI上的透明颜色。我发现最好选择颜色列表底部附近的clNone。这样可以确保在位图添加到图像列表时,不会对其应用透明度

这意味着图像列表中的位图显示其“背景”,设计器中第二个按钮上的图像也显示该颜色,但是,当单击第一个按钮时,图像更改为“100”,但现在应用了透明度

这是因为从Canvas.Pixels[0,31]返回的颜色值是实际的颜色值,而不是一些看起来像16777215但实际上不是的伪内部合成的东西。这允许ReplaceMasked调用正常工作