Delphi:GR32在TBitmap32上绘制带有alpha的PNG,而不清除其内容

Delphi:GR32在TBitmap32上绘制带有alpha的PNG,而不清除其内容,delphi,png,transparent,alpha,Delphi,Png,Transparent,Alpha,在浏览了其他几个相关问题后,我无法找到一个适用于此的代码,因此请不要使用“重复问题”标签 给定一个具有每像素alpha通道或单色透明度的PNG图像,我需要代码将其绘制到已经包含图像的TBitmap32上(在PNG部分之前会绘制一些图形)。假设我的TBitmap32是200x200,我在上面画了一些图,然后我想在当前内容的顶部插入一个更小的透明PNG图像,透明地根据PNG的alpha通道数据或单色alpha Uses pngimage, GR32; procedure TForm1.Button

在浏览了其他几个相关问题后,我无法找到一个适用于此的代码,因此请不要使用“重复问题”标签

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

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:

迄今为止的结果:


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

  • 将它们加载到中间TBitmap32位图中,然后操作这些TBitmap32位图。
  • 正如您所指出的,直接在目标画布上使用TPngImage.Draw(使用Delphi XE2和更高版本在Vcl.Imaging.pngimage中实现)。 在透明度方面,第二种方法更可取,因为您可能会发现将PNG加载到TBitmap32中的代码可能无法正常工作。下面是两个最常使用的错误代码示例:

    (1) “LoadPNGintoBitmap32”来自 -它会应用透明度两次,因此alpha值不是0或255的图像看起来与其他软件中的图像不同(在具有玻璃效果的半透明图像上最为明显)。这段代码将首先将alpha应用于RGB,然后设置alpha,所以当您感到疼痛时,将再次应用alpha。您可以在此处找到有关此问题的更多信息: . 此外,它不能正确地将调色板图像的透明度转换为TBitmap32的alpha层,例如,所有白色像素都变为透明

    (2) gr32ex库中的“LoadBitmap32FromPNG”: -与(1)相同算法的实现略有不同,并且与(1)具有相同的问题

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

  • 确保您的代码正确地将PNG转换为TBitmap32。
  • 不要使用透明图像的TBitmap32直接在HDC、画布或TBitmap上绘制。使用dmBlend和DrawTo或BlockTransfer()在另一个TBitmap32上绘制。例如,要在TBitmap上透明地绘制,请创建中间缓存TBitmap32:
  • 将图像从TBitmap复制到缓存TBitmap32;
  • 使用DrawTo或BlockTransfer()将透明图像应用到缓存TBitmap32,避免使用Canvas或HDC混合两个图像,因为它们会丢失alpha层信息;
  • 将图像从缓存TBitmap32复制回您的TBitmap。
    那么,有什么不符合你的预期呢?我看到绿色图片很好地融入到黑色背景中,所以PNG alpha透明度得以保持。这是黑色背景的问题吗?如果是,在对bm32位图进行任何绘图之前,请使用透明颜色填充整个位图。我假设新位图的默认颜色可能是黑色或白色,并且可能是完全不透明的。黑色区域应该是透明的,混合在下面的另一个位图32(红色)Nvm it上。。我很愚蠢,最明显和最简单的步骤出乎意料地完成了任务:p.Draw(b32.Canvas,Rect(50100150200));德尔福西雅图版本的TPngImage完美地完成了这项工作: