经历了其他几个相关问题之后,我无法为此提供有效的代码,因此请保留“重复问题”标签。

给定具有每个像素Alpha通道或单色透明性的PNG图像,我需要代码将其绘制到已经包含图像的TBitmap32上(在PNG部分之前进行了一些绘制)。假设我的TBitmap32是200x200,我在上面做了一些绘图,然后我想根据PNG的Alpha通道数据或单色Alpha透明地在其当前内容之上插入一个较小的透明PNG图像。

Uses pngimage, GR32;

procedure TForm1.Button1Click(Sender: TObject);
Var b: TBitmap;
    b32: TBitmap32;
    p: TPngImage;
begin
  b   := TBitmap.Create;
  b32 := TBitmap32.Create;
  p   := TPngImage.Create;

  // 50x50 PNG
  p.LoadFromFile('z:\test2.png');

  b.Width    := 200;
  b.Height   := 200;
  b32.Width  := 200;
  b32.Height := 200;
  // some drawing happens on the b32~

  // insert code here to draw the png onto the b32, on top of
  // what's already drawn, and at specific coordinates i.e 10,10


  /////////////////////////////

  b32.DrawTo(b.Canvas.Handle,0,0);
  Canvas.Draw(0,0,b);

  p.Free;
  b32.Free;
  b.Free;
end;


原始PNG:

delphi - Delphi:GR32在不清除其内容的情况下将带有Alpha的PNG绘制到TBitmap32上-LMLPHP

到目前为止的结果:

delphi - Delphi:GR32在不清除其内容的情况下将带有Alpha的PNG绘制到TBitmap32上-LMLPHP

最佳答案

有两种使用透明PNG文件的方式:


将它们加载到中间的TBitmap32位图中,然后操作这些TBitmap32位图。
如您所指出的,直接在目标Canvas上使用TPngImage.Draw(在Delphi XE2和更高版本的Vcl.Imaging.png图像中实现)。


关于透明度,第二种方法更可取,因为您可能会发现将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层,例如,所有白色像素都变为透明。

(2)来自gr32ex库的“ LoadBitmap32FromPNG”:https://code.google.com/archive/p/gr32ex/
-与(1)相同的算法的实现略有不同,并且具有与(1)相同的问题。

如果仍然喜欢使用TBitmap32,请执行以下步骤序列:


确保您的代码正确将PNG转换为TBitmap32。
请勿将TBitmap32与透明图像一起使用,以直接在HDC,Canvas或TBitmap上绘制。使用dmBlend和DrawTo或BlockTransfer()在另一个TBitmap32上绘制。例如,要在TBitmap上透明地绘制,请创建一个中间缓存TBitmap32:
将图像从TBitmap复制到缓存TBitmap32;
使用DrawTo或BlockTransfer()将透明图像应用于缓存TBitmap32,避免使用Canvas或HDC混合两个图像,因为它们会丢失alpha层信息;
将图像从缓存TBitmap32复制回您的TBitmap。

关于delphi - Delphi:GR32在不清除其内容的情况下将带有Alpha的PNG绘制到TBitmap32上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39812396/

10-13 07:25