title: Paint PNG image on other PNG
body: <p>How to merge two PNG's together? I know that you can't use <code>PNGObject.Draw</code> because it doesn't copy alpha transaperncy (I am not sure but it doesn't work anyway) so custom procedure/function is needed. I didn't come with <em>empty hands</em>, I have this procedure:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>But sadly it doesn't work how it should, it does the job but not right. When it merges empty image with loaded image, it works fine, but when both images aren't empty, it makes them loss transparancy.</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>Wanted result:</p>
  
  <p><img src="https://i.stack.imgur.com/FT9IE.png" alt="enter image description here"></p>
  
  <p>Actual result:</p>
  
  <p><img src="https://i.stack.imgur.com/HuyvL.png" alt="enter image description here"></p>
  
  <p>I am not sure if you can see differences between these imgaes, but you should open these in PNG editor software and you will see the difference. So I need other procedure to merge PNGs. I am using newest version of <code>PNGImage</code> by the way.</p>
  
  <p>Thanks and have a good day!</p>