首页 文章

Delphi:GR32将带有alpha的PNG绘制到TBitmap32而不清除其内容

提问于
浏览
1

在经历了其他几个相关的问题后,我无法为此提出一个有效的代码,所以请备用“重复的问题”标签 .

给定具有每像素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:

enter image description here

结果到目前为止:

enter image description here

1 回答

  • 2

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

    • 将它们加载到中间TBitmap32位图中,然后操作这些TBitmap32位图 .

    • 正如您所指出的那样,直接在目标Canvas上使用TPngImage.Draw(在Vcl.Imaging.pngimage中与Delphi XE2及更高版本一起实现) .

    第二种方法在透明度方面更受欢迎,因为您可能会发现将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 .

相关问题