5

Delphi 2006 的 TImage 不太支持 PNG。为了在我的表单上显示具有 alpha 透明度的图像,我必须在运行时加载它们。我可以在设计时加载它们,但它们无法生存,我认为是因为 PNG 没有保存在 DFM 文件中。我确信这在最新的 Delphi 中都是笨拙的,但我目前无法升级。

无论如何,我在运行时加载它们:

Image1.Picture.Assign (PngImageCollection1.Items [0].PNGImage) ;

PNGImageCollection 组件包含我所有的各种大小的 PNG(这些是在设计时创建和加载的),我将它们分配给 FormCreate 事件中的相应 TImage。

这工作正常,直到我遇到问题,在表格上使用这些图像后,我试图在其他地方重用这些图像。我发现分配 TPicture 的行为已将其设置为空图像作为分配的结果。这发生在例程 TPicture.ForceType 中,AFAICT 检查 FGraphic 的类型,如果它不是所需的类型,它会释放 FGraphic 并创建所请求类型的新实例。

好的。因此,经过一番摸索,我发现也许我真的应该这样做:

Image1.Picture.Bitmap.Assign (PngImageCollection1.Items [0].PNGImage) ; 

这起到了作用,因为分配没有破坏图像,但图像现在显示为不透明的半透明位,即:

使用 Image1.Picture.Bitmap.Assign 分配时的 TImage

代替:

使用 Image1.Picture.Assign 分配时的 TImage

如何让此图像正确显示 alpha 透明位?(和补充问题:Image1.Picture.Bitmap.Assign 是正确的方法吗?)。

这是更详细的代码:

在我遇到“重用”TImage 问题的代码中,顺序是:
在表单创建上:

LogoImage.Picture.Assign (PngImageCollection1.Items [0].PNGImage) ; 

(PNGIMage 是公司标志,LogoImage1 在主窗体上)。

在打印报告标题上:

procedure PrintLogo (Report : TBaseReport) ;

var
    X1, Y1, LogoHeightMM    : Double ;

begin
with Report do
    begin
    LogoHeightMM  := CalcGraphicHeight (LogoWidthMM, MainForm.LogoImage.Picture.Graphic) ;
    X1            := PageWidth - MarginRight - LogoWidthMM ;
    Y1            := SectionBottom - LogoHeightMM ;
    PrintBitmapRect (X1, Y1, X1 + LogoWidthMM, Y1 + LogoHeightMM, MainForm.LogoImage.Picture.Bitmap) ;
    end ;
end ;

第一次调用打印徽标的例程时,它会正常执行,但在调用 PrintBitmapRect 后,LogoImage .Picture 会被清除。下次调用打印头例程时,对 CalcGraphicHeight 的调用将失败,因为图像的宽度和高度为零。

将 Picture.Assign 更改为 Picture.Bitmap.Assign 修复了标题打印例程中的 RTE,但是当我将相同的“修复”移植到从 PNG 分配的其他静态图像(如上面的齿轮)时,我失去了 aplha 通道。

4

1 回答 1

5

您没有显示代码中真正相关的部分:您如何重新使用会导致其具有特定类型的图像。

当您将 TImage 分配给 TPngObject 时,图像的图形包含一个 png 对象。只有当您专门请求位图时,它才会强制其图形为位图类型。比如这个,

  Bmp.Assign(Image1.Picture.Bitmap);

将强制 Image1 具有位图图形,如果其图形是 png 对象,它将被释放。而这,

  Bmp.Assign(Image1.Picture.Graphic);

不会强制 Image1 具有位图图形,png 对象将执行分配并留在那里。

Delphi 的位图(至少到最近的版本)不支持 alpha 通道,因此您不应该将其Image1.Picture.Bitmap.Assign(..用于部分透明的图像。


顺便说一句,您可以使用 png 图像集合中的图像作为源,而不是重新使用图像中的图形。

于 2011-03-21T03:12:53.073 回答