2015-08-28 226 views
3

我有一个PNG,我想加载TBitmap32。透明PNG到TBitmap32

后我打开我所说的位图:

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

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

enter image description here

这是实际的图像:

enter image description here

+0

你为什么要设置'DrawMode'和'OuterColor'?这听起来像你得到了你所要求的。换句话说,“TBitmap32”肯定会尊重图片的Alpha透明度。 –

回答

4

似乎TBitmap32可能失去阿尔法信息,同时加载PNG图像

您可以考虑使用一个文件摘录如下,其中的GR32_PNG

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

Graphics32


单位的代码使用示例可以如下改变,以满足您的需求:

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

的问题可能是PNG已经错误地转换到TBitmap32,失去在运输途中的透明度信息。这是调色板PNG图像的常见情况。否则,您不必使用“Bitmap.DrawMode:= dmTransparent”和“OuterColor”。如果来自PNG的透明信息将正确传输到TBitmpa32,则DrawMode:= dmBlend可以工作,而不需要设置OuterColor。

最重要的是您如何将PNG加载到TBitmap32中。来自Vcl.Imaging的TPngImage。pngimage单元(在Delphi XE2和更高版本中实现)可以在位图上透明地绘制,保留位图上的内容,使用PNG alpha图层组合颜色等,但不能轻松转换各种PNG透明度格式(包括调色板)转换为TBitmap32每个像素的alpha分量。一旦TPngImage绘制图像,您将得到每个像素的组合RGB,但alpha分量不会传输到目标位图。

有迹象表明,尝试将PNG加载与透明度TBitmap32提供帮助程序,但他们也有缺点:

(1)从http://graphics32.org/wiki/FAQ/ImageFormatRelated “LoadPNGintoBitmap32” - 它适用透明度的两倍,因此与图像除0或255以外的Alpha值与其他软件(在玻璃效果的半透明图像上最明显)看起来不同。此代码首先将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/

既然你现在在这个问题上的所有信息,你可以选择适合您的解决方案。