我有一个png,我想在TBitmap32中加载。
加载位图后,我调用:
Bitmap.DrawMode := dmTransparent;
Bitmap.OuterColor := Bitmap.PixelS[0,0];
然后所有白色像素都是透明的。我怎么能只为png图像的透明部分做到这一点?这是我的图像,图像边缘的alpha透明度以标准方式显示。
这是实际图片:
答案 0 :(得分:6)
加载 PNG 图片时似乎TBitmap32
可能会丢失 alpha 信息。
您可以考虑使用文档摘录如下的GR32PNG library:
。 。 。由于读写使用中间TBitmap对象,因此需要不必要的额外存储器来存储位图数据。此外,通过将数据转换为TBitmap格式或从TBitmap格式转换数据,附加信息可能会丢失或处理错误。 。 。
要通过Graphics32本机处理PNG文件,可以使用第三方库GR32 PNG库。此库使用本机PNG格式作为中间存储。通过分配TBitmap32对象,数据可以动态地编码/解码到PNG。使用此库还可以访问存储在PNG文件中的其他信息。
本机的代码使用示例可以根据您的需要进行更改:
var
AlphaChannelUsed: Boolean;
begin
LoadBitmap32FromPNG(Bitmap, <your path to the PNG image>, AlphaChannelUsed);
if AlphaChannelUsed then
Bitmap.DrawMode := dmBlend
else
Bitmap.DrawMode := dmOpaque;
end;
其中Bitmap
是TBitmap32
个对象。
生成的图像以TImage32
组件中的形式加载:
答案 1 :(得分:3)
问题可能是PNG错误地转换为TBitmap32,丢失了传输中的透明度信息。这是调色板PNG图像的常见情况。否则,您不必使用“Bitmap.DrawMode:= dmTransparent”和“OuterColor”。如果来自PNG的透明信息信息已正确传输到TBitmpa32,则DrawMode:= dmBlend将起作用,而无需设置OuterColor。
最重要的是如何将PNG加载到TBitmap32中。来自Vcl.Imaging.pngimage单元的TPngImage(在Delphi XE2及更高版本中实现)可以在位图上透明地绘制,保留位图上的内容,使用PNG alpha层组合颜色等,但它不允许轻松转换各种将PNG透明度(包括调色板)格式转换为TBitmap32每个像素的alpha分量。 TPngImage绘制图像后,您将获得每个像素的组合RGB,但alpha分量不会传输到目标位图。
有一些辅助例程可以尝试将PNG加载到具有透明度的TBitmap32中,但它们有缺点:
(1)来自http://graphics32.org/wiki/FAQ/ImageFormatRelated的“LoadPNGintoBitmap32” - 它应用透明度两次,因此alpha值不是0或255的图像看起来与其他软件不同(最常见的是带有玻璃效果的半透明图像)。此代码首先将alpha应用于RGB,然后将alpha设置为单独的图层,因此在绘制时,将再次应用alpha。您可以在此处找到有关此问题的更多信息:Delphi, GR32 + PngObject: converting to Bitmap32 doesn't work as expected 。除此之外,它没有正确地将透明度从调色图像转换为TBitmap32的alpha层。他们手动为输出位图的某种颜色(渲染为RGB)的像素设置Alpha透明度,而不是在渲染为RGB之前执行此操作,因此当所有白色像素都是透明的时,实际透明度会丢失,就像样本图像上一样。
(2)gr32ex库中的“LoadBitmap32FromPNG”:https://code.google.com/archive/p/gr32ex/ - 与(1)相同算法的略有不同的实现,并且具有与(1)相同的问题。
所以,解决方案是:
由于您现在掌握了有关此问题的所有信息,因此您可以选择适合您的解决方案。