微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Delphi,GR32 PngObject:转换为Bitmap32不能按预期工作

我正在使用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+ 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
 { ... }

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来了,并在其上添加了另一层透明度.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐