我正在使用 GR32 绘制多个半透明 PNG 图像。
到目前为止我一直在使用以下方法:
png:= TPNGObject.Create;
png.LoadFromFile(...);
PaintBox321.Buffer.Canvas.Draw(120, 20, png);
但是我想切换到 GR32 网站上提出的方法(http://graphics32.org/wiki/FAQ/ImageFormatRelated) :
tmp:= TBitmap32.Create;
LoadPNGintoBitmap32(tmp, ..., foo);
tmp.DrawMode:= dmBlend;
PaintBox321.Buffer.Draw(Rect(20, 20, 20+ tmp.Width, 20+tmp.Height),
tmp.ClipRect, tmp);
虽然第一种方法工作得很好,但第二种方法(应该给出相同的结果)会导致 alpha 通道出现非常奇怪的问题,请参见图像(它还显示了与 Paint.NET 中“排列”的相同图像的比较 - 背景和图标在编辑器的图层上打开)。该图像显示 Bitmap32 加载或绘制不正确。有小费吗?
-- 11 月 22 日添加
我发现这不是关于绘图,而是关于将PNG加载到BMP32。从 BMP32 保存回 PNG 会生成不正确的“变白”(左侧)PNG 图像。
原因似乎是加载时透明度被应用到图像两次LoadPNGintoBitmap32
,使其看起来更加透明和偏灰色(稍后会详细介绍)。
首先是透明度:
这是原始代码LoadPNGintoBitmap32
,关键部分标有注释:
PNGObject := TPngObject.Create;
PNGObject.LoadFromStream(srcStream);
destBitmap.Assign(PNGObject); // <--- paint to destBitmap's canvas with transparency (!)
destBitmap.ResetAlpha;
case PNGObject.TransparencyMode of // <--- the following code sets the transparency again for the TBitmap32
{ ... }
The destBitmap.Assign
内部的做法与之前的方法相同:它让 PNG 图像将自身绘制到画布上。此操作尊重 PNG 的 Alpha 通道。但这不是必需的,因为 alpha 通道已分配给TBitmap32
第二步的像素!
现在将代码修改如下,关键部分再次标注注释:
PNGObject := TPngObject.Create;
PNGObject.LoadFromStream(srcStream);
PNGObject.RemoveTransparency; // <--- paint PNG without any transparency...
destBitmap.Assign(PNGObject); // <--- ...here
destBitmap.ResetAlpha;
srcStream.Position:=0;
PNGObject.LoadFromStream(srcStream); // <--- read the image again to get the alpha channel back
case PNGObject.TransparencyMode of // <--- this is ok now, the alpha channel now only exists in the TBitmap32
{ ... }
上述解决方案效率低下,因为它读取了两次图像。但它说明了为什么第二种方法会产生更透明的图像。
对于灰色:原始代码中还有一个问题:destBitmap.Assign
首先填充背景clWhite32
,然后将图像透明地绘制到其上。进而LoadPNGintoBitmap32
来并在其之上添加另一层透明度。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)