无论如何,我在运行时加载它们:
Image1.Picture.Assign (PngImageCollection1.Items [0].PNGImage) ;
PNGImageCollection组件包含各种大小的PNG(这些PNG在设计时创建和加载),我将它们分配给FormCreate事件中的相应TImages.
这个工作正常,直到我遇到一个问题,我试图在表单上使用它之后在其他地方重用其中一个图像.我发现分配TPicture的行为已将其设置为由于Assign而导致的空图像.这发生在例程TPicture.ForceType中,AFAICT检查FGraphic的类型,如果它不是所需类型,它将释放FGraphic并创建所请求类型的新实例.
好.所以在经过一番搔痒之后,我发现也许我应该这样做:
Image1.Picture.Bitmap.Assign (PngImageCollection1.Items [0].PNGImage) ;
这就是诀窍,因为Assign没有破坏图像,但现在图像显示半透明位是不透明的,即:
代替:
如何让此图像正确显示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,X1 + LogoWidthMM,Y1 + LogoHeightMM,MainForm.LogoImage.Picture.Bitmap) ; end ; end ;
第一次打印徽标的例程被调用时,它会毫无错误地执行,但是在调用PrintBitmapRect之后,LogoImage .Picture会被清除.下次调用打印头例程时,对CalcGraphicHeight的调用将失败,因为图像的宽度和高度为零.
更改Picture.Assign到Picture.Bitmap.Assign修复标题打印例程中的RTE,但是当我将相同的“修复”移植到从PNG分配的其他静态图像(如上面的齿轮)时,我丢失了aplha通道.
解决方法
为TImage分配TPngObject时,图像的图形包含png对象.只有当您特别请求位图时,它才会强制其图形为位图类型.例如,这个,
Bmp.Assign(Image1.Picture.Bitmap);
将强制Image1有一个位图图形,如果它的图形是一个png对象,它将被释放.这个,
Bmp.Assign(Image1.Picture.Graphic);
不会强制Image1有一个位图图形,png对象将执行赋值并保持在那里.
Delphi的位图(至少是最新版本)不支持alpha通道,所以你不应该使用Image1.Picture.Bitmap.Assign(..对于部分透明的图像.
顺便说一句,您可以使用png图像集合中的图像作为源,而不是重新使用图像中的图形.