首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在其他PNG上绘制PNG图像

在其他PNG上绘制PNG图像
EN

Stack Overflow用户
提问于 2012-05-01 06:00:44
回答 1查看 3.2K关注 0票数 2

如何将两个巴布亚新几内亚合并在一起?我知道您不能使用PNGObject.Draw,因为它不复制alpha transaperncy (我不确定,但它无论如何都不起作用),所以需要定制过程/函数。我不是空着手来的,我有个手术:

代码语言:javascript
复制
procedure MergePNGLayer(Layer1,Layer2: TPNGObject; Const aLeft,aTop:Integer);
var
  x, y: Integer;
  SL1,  SL2,  SLBlended : pRGBLine;
  aSL1, aSL2, aSLBlended: PByteArray;
  blendCoeff: single;
  blendedPNG, Lay2buff: TPNGObject;
begin
  blendedPNG:=TPNGObject.Create;
  blendedPNG.Assign(Layer1);
  Lay2buff:=TPNGObject.Create;
  Lay2buff.Assign(Layer2);
  SetPNGCanvasSize(Layer2,Layer1.Width,Layer1.Height,aLeft,aTop);
  for y := 0 to Layer1.Height-1 do
  begin
    SL1 := Layer1.Scanline[y];
    SL2 := Layer2.Scanline[y];
    aSL1 := Layer1.AlphaScanline[y];
    aSL2 := Layer2.AlphaScanline[y];
    SLBlended := blendedPNG.Scanline[y];
    aSLBlended := blendedPNG.AlphaScanline[y];
    for x := 0 to Layer1.Width-1 do
    begin
      blendCoeff:=aSL1[x] * 100/255/100;
      aSLBlended[x] := round(aSL2[x] + (aSL1[x]-aSL2[x]) * blendCoeff);
      SLBlended[x].rgbtRed   := round(SL2[x].rgbtRed + (SL1[x].rgbtRed-SL2[x].rgbtRed) * blendCoeff);
      SLBlended[x].rgbtGreen := round(SL2[x].rgbtGreen + (SL1[x].rgbtGreen-SL2[x].rgbtGreen) * blendCoeff);
      SLBlended[x].rgbtBlue  := round(SL2[x].rgbtBlue + (SL1[x].rgbtBlue-SL2[x].rgbtBlue) * blendCoeff);
    end;
  end;
Layer1.Assign(blendedPNG);
Layer2.Assign(Lay2buff);
blendedPNG.Free;
Lay2buff.Free;
end;

但遗憾的是,它并没有发挥应有的作用,而是发挥了作用,但却不正确。当它将空图像和加载的图像合并时,它工作得很好,但是当两个图像都不是空的时候,就会使它们失去透明性。

代码语言:javascript
复制
procedure TForm1.FormClick(Sender: TObject);
var
PNG1, PNG2, PNG3, Dest: TPNGObject;
begin
PNG1 := TPNGObject.Create;
PNG2 := TPNGObject.Create;
PNG3 := TPNGObject.Create;

PNG1.LoadFromFile('Aero\TopLeft.png');//Width 10
PNG2.LoadFromFile('Aero\Top.png');//Width 200
PNG3.LoadFromFile('Aero\TopRight.png');//Width 10

Dest := TPNGObject.CreateBlank(COLOR_RGBALPHA, 16, 220, 10);
MergePNGLayer(Dest, PNG1, 0, 0);
MergePNGLayer(Dest, PNG2, 10, 0);
MergePNGLayer(Dest, PNG3, 210, 0);
Dest.SaveToFile('C:\OUT.PNG');
end;

通缉结果:

实际结果:

我不确定您是否能看到这些imgaes之间的差异,但是您应该在PNG编辑器软件中打开这些,这样您就会看到不同之处。所以我需要其他程序来合并PNG。顺便说一下,我正在使用最新版本的PNGImage

谢谢,祝你今天愉快!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-01 06:31:06

这似乎挺好的:

代码语言:javascript
复制
procedure DrawPngWithAlpha(Src, Dest: TPNGObject; const R: TRect);
var
  X, Y: Integer;
  Alpha: PByte;
begin
  Src.Draw(Dest.Canvas, R);

  // I have no idea why standard implementation of TPNGObject.Draw doesn't apply transparency.
  for Y := R.Top to R.Bottom - 1 do
    for X := R.Left to R.Right - 1 do
    begin
      Alpha := @Dest.AlphaScanline[Y]^[X];
      Alpha^ := Min(255, Alpha^ + Src.AlphaScanline[Y - R.Top]^[X - R.Left]);
    end;
end;
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10394151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档