Delphi 2009中的Imagelists和Images中的PNGs

4

D2009引入了对图像和图像列表的PNG支持。

然而...

我有一个包含alpha的png图像的imagelist。我想使用TImage将其中一个放在表单上。我该如何做到这一点并使图像合成得很好?

作为我所面临问题的一个例子,下面的代码无法正常工作,并产生如下效果:

ImageList.GetBitmap(index, Image1.Picture.Bitmap);

alt text
(来源: clip2net.com)

更详细地解释一下:

将Timage拖到窗体上,在设计时,使用Picture属性加载一个带有alpha通道的PNG文件。请注意,它与窗体正确合成并具有完全透明度。

现在,在设计时,添加第二个空的Timage,添加一个TImagelist,并向imagelist添加相同的PNG。如何将TImageList中的PNG分配给第二个TImage,并使其看起来与第一个图像相同?


而且,那绝对不像Delphi代码。你确定这是正确的语言吗? - Argalatyr
我支持前面两条评论。 ;) - Oliver Giesen
@Ken - 你说得对,关于C++Builder的部分我会进行修改。 - Roddy
1
如果您仍然拥有原始图像,直接将其重新上传到stackoverflow而不是第三方网站会很有帮助。谢谢。 - Jessica Brown
6个回答

4

根据我的研究,我发现TImageList将图像存储为TBitmaps,因此alpha信息在存储时丢失,并且您无法通过当前的TImageList实现所需的效果。

更新:

经过更多实验和下面的代码,我可以使透明度正常工作。

ImageList1.ColorDepth := cd32Bit;
Image2.Transparent := True;
Image2.Canvas.Pen.Style := psClear;
Image2.Canvas.Rectangle(0, 0, Image2.Width+1, Image2.Height+1);
ImageList1.Draw(Image2.Canvas, 0,0,0);

但是它看起来没有加载好的png图片那么漂亮。

不,alpha信息并没有丢失。您可以使用TImageList和TButton,使按钮上的透明图像正确显示。此外,位图也可以是32 bpp... - Roddy

2

在项目 -> 选项 -> 应用程序选项卡中的“启用运行时主题”中进行勾选。

这个方法解决了我在RAD Studio 2010中遇到的问题。


1
我刚刚尝试了一个简单的测试。TImageList 包含一个带有透明度的 PNG 图像。我使用以下方式将该图像呈现在第二个 TImage 上:
imlImageList.Draw(img2.Canvas, 0, 0, 0);
对我来说产生差异的是设置 img2.Transparent := true(我使用了设计器,而不是代码)。

这对我不起作用 - 我得到了与上面显示的相同的结果。你确定你的PNG有适当的软边透明度吗? - Roddy
Alpha透明度在TIMageList中使用时变得简单,因为这是MS Common Controls库的设计,将BMP颜色作为透明色。这甚至不是Delphi代码,而是Windows本身实现的。 - Warren P

1
我偶然发现了这个讨论串:

Tranparent PNGs in D2009 TImageList

@Pekka Nyyssonen:将ColorDepth设置为cd32Bit,将DrawingStyle设置为dsTransparent对我有用。

我自己没有访问Delphi 2009,所以我还没有尝试过...


0
据我所知,这是无法实现的。给出的建议都不能得到一个正确的 alpha-blended 图像,这是主要的要求。
也许通过定义一个派生自 TImageList 的类,可以访问受保护的方法,从而使某些东西能够工作。目前我的解决方案是使用第三方定制的 ImageList 组件来实现这一点。

0

有几种方法可以将透明图像添加到图像列表中。

使用AddMasked或InsertMasked,您可以添加一个图像并标记一个颜色作为透明颜色:

procedure InsertMasked(Index: Integer; Image: TBitmap; MaskColor: TColor);
function AddMasked(Image: TBitmap; MaskColor: TColor): Integer;

使用插入或添加功能,您可以添加图像和蒙版。蒙版是一种两种颜色(黑色/白色)的图像,只有来自图像的白色像素被使用,其他像素是透明的。

function Add(Image, Mask: TBitmap): Integer;
procedure Insert(Index: Integer; Image, Mask: TBitmap);

谢谢,但我需要像左边图片展示的透明混合,而不是单位掩码。 - Roddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接