1

我最近遇到了一种情况,我需要为用于导航栏的图像编写计数器,其中图像来自 imagelist 组件。

在绞尽脑汁看了几个小时后,查看了其他文章,例如:

如何从 ImageList 加载透明图像?

如果使用 v6 ImageList 控件,*.bmp 会丢失透明背景

http://codeverge.com/embarcadero.delphi.graphics/timage-is-not-transparent-after-a/1080826

http://www.efg2.com/Lab/Library/Delphi/Graphics/ICOtoBMP.pas.txt

我选择了一个解决方案,从图像列表中复制位图,将文本写入位图画布,然后将位图放回图像列表中。

唯一的问题是我失去了透明度,我一生都无法弄清楚如何找回它。

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

如果我设置颜色以使图像在链接到图像列表的组件中看起来正确,比如我的导航栏,那么当您使用 GetBitmap 提取图像时,透明度会丢失,并且在直接应用于TImage时看起来是白色的。

好的。没问题。只需使用白色作为透明色...

没有。即使将 16777215 显示为颜色,与clWhiteCanvas.Pixels[0, 31]的值相同,但将其用于TransparentColour没有任何效果。

要明白我的意思,请在 Delphi 中创建一个新的 VCL 表单应用程序,放置几个TButtons和一个TImageList ,然后通过在设计器中设置按钮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 像素位图)。默认情况下,组件将透明颜色显示为左下角的像素。保持原样并确定图像列表更改。将第二个按钮的ImageIndex更改为 0。

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

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

4

1 回答 1

1

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

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

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

于 2019-07-04T05:40:50.553 回答