【问题标题】:Transparent Png to TBitmap32透明PNG到TBitmap32
【发布时间】:2015-08-28 08:11:05
【问题描述】:

我有一个 png,我想将它加载到 TBitmap32 中。

加载位图后我调用:

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

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

这是实际的图像:

【问题讨论】:

  • 你为什么要设置DrawModeOuterColor?听起来你得到了你想要的。换句话说,TBitmap32 肯定会尊重您图像的 Alpha 透明度。

标签: delphi alpha-transparency graphics32


【解决方案1】:

问题可能是 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) “LoadPNGintoBitmap32”来自http://graphics32.org/wiki/FAQ/ImageFormatRelated - 它应用了两次透明度,因此 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/

既然您现在掌握了有关此问题的所有信息,您可以选择适合您的解决方案。

【讨论】:

    【解决方案2】:

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

    您可以考虑使用GR32PNG library,其文档摘录如下:

    。 . .
    由于读取和写入使用中间 TBitmap 对象,因此需要不必要的额外内存来存储位图数据。此外,通过将数据与 TBitmap 格式相互转换,其他信息可能会丢失或处理错误。
    。 . .
    要通过 Graphics32 本地处理 PNG 文件,可以使用第三方库 GR32 PNG 库。该库使用原生 PNG 格式作为中间存储。通过分配一个 TBitmap32 对象,数据被即时编码/解码到 PNG 或从 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 组件内的表单中加载的结果图像:

    【讨论】:

      猜你喜欢
      • 2013-03-09
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2020-04-13
      • 2013-01-07
      • 1970-01-01
      • 2010-10-16
      • 2013-12-10
      相关资源
      最近更新 更多