TBitmap32的透明Png

时间:2015-08-28 08:11:05

标签: delphi alpha-transparency graphics32

我有一个png,我想在TBitmap32中加载。

加载位图后,我调用:

Bitmap.DrawMode   := dmTransparent;
Bitmap.OuterColor := Bitmap.PixelS[0,0];

然后所有白色像素都是透明的。我怎么能只为png图像的透明部分做到这一点?这是我的图像,图像边缘的alpha透明度以标准方式显示。

enter image description here

这是实际图片:

enter image description here

2 个答案:

答案 0 :(得分:6)

加载 PNG 图片时似乎TBitmap32可能会丢失 alpha 信息。

您可以考虑使用文档摘录如下的GR32PNG library

  

。 。 。由于读写使用中间TBitmap对象,因此需要不必要的额外存储器来存储位图数据。此外,通过将数据转换为TBitmap格式或从TBitmap格式转换数据,附加信息可能会丢失或处理错误。 。 。
  要通过Graphics32本机处理PNG文件,可以使用第三方库GR32 PNG库。此库使用本机PNG格式作为中间存储。通过分配TBitmap32对象,数据可以动态地编码/解码到PNG。使用此库还可以访问存储在PNG文件中的其他信息。

Graphics32 project page

本机的代码使用示例可以根据您的需要进行更改:

var
  AlphaChannelUsed: Boolean;
begin
  LoadBitmap32FromPNG(Bitmap, <your path to the PNG image>, AlphaChannelUsed);

  if AlphaChannelUsed then
    Bitmap.DrawMode := dmBlend
  else
    Bitmap.DrawMode := dmOpaque;
end;

其中BitmapTBitmap32个对象。

生成的图像以TImage32组件中的形式加载:

enter image description here

答案 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)相同的问题。

所以,解决方案是:

  1. 不要使用TBitmap32;使用Vcl.Imaging.pngimage.TPngImage直接在目标位图(屏幕等)上绘制 - 这是正确处理各种PNG格式的最兼容方式。
  2. 使用帮助程序路由将透明度信息从Vcl.Imaging.pngimage.TPngImage传输到TBitmap32。
  3. 使用GR32 PNG库https://sourceforge.net/projects/gr32pnglibrary/
  4. 由于您现在掌握了有关此问题的所有信息,因此您可以选择适合您的解决方案。