Reputation: 742
I want to copy the content of a PNG image to another bigger one. Source image is 16x16x32b, the destination is of the same format but two times broader. However the code below produces empty image. Changing COLOR_RGBALPHA to COLOR_RGB produces non transparent PNG. How to make it properly?
var
png, pngsrc: TPngImage;
begin
png := TPngImage.CreateBlank(COLOR_RGBALPHA, 8, 32, 16);
pngsrc := TPngImage.Create;
try
pngsrc.LoadFromFile('c:\src.png');
pngsrc.Draw(png.Canvas, Rect(16, 0, 32, 16));
png.SaveToFile('c:\dst.png');
finally
png.Free;
pngsrc.Free;
end;
Upvotes: 1
Views: 1363
Reputation: 46
Copying a PNG with transparency into a larger PNG image can be achieved by transferring the alpha data as a separate step, as per the following code.
var
png, pngsrc: TPngImage;
X: Integer;
Y: Integer;
XOffset: Integer;
YOffset: Integer;
srcAlphaArray: pByteArray;
destAlphaArray: pByteArray;
begin
// Inspired by https://www.bverhue.nl/delphisvg/2016/09/26/save-bitmap-with-transparency-as-png-in-vcl/
// Optional X and Y offsets to position source png into destination png
XOffset := 16;
YOffset := 0;
png := TPngImage.CreateBlank(COLOR_RGBALPHA, 8, 32, 16);
png.CreateAlpha;
png.Canvas.CopyMode := cmSrcCopy;
pngsrc := TPngImage.Create;
try
pngsrc.LoadFromFile('c:\src.png');
pngsrc.Draw(png.Canvas, Rect(XOffset, YOffset, pngsrc.Width + XOffset, pngsrc.Height + YOffset));
if pngsrc.TransparencyMode = ptmPartial then
begin
// Update destination png with tranparency data from original
for Y := 0 to Pred(pngsrc.Height) do
begin
srcAlphaArray := pngsrc.AlphaScanline[Y];
destAlphaArray := png.AlphaScanline[Y + YOffset];
for X := 0 to Pred(pngsrc.Width) do
begin
destAlphaArray^[X + XOffset] := srcAlphaArray^[X];
end;
end;
end;
png.SaveToFile('c:\dst.png');
finally
png.Free;
pngsrc.Free;
end;
end;
Upvotes: 1