PNG to TBitmap (preserving transparency)

347 views Asked by At

I use Delphi 10.3.3 VCL.

I want to load a PNG image, convert to TBitmap (in order to make some modifications), then save it as PNG.

I use this code, but it loses transparency. Transparent background becomes black.

var
  InputPNG: TPngImage;
  OutputPNG: TPngImage;
  BMP: TBitmap;
begin
  InputPNG  := TPngImage.Create;
  OutputPNG := TPngImage.Create;
  BMP := TBitmap.Create;

  InputPNG.LoadFromFile('C:\input.png');
  BMP.Assign(InputPNG);

  OutputPNG.Assign(BMP);
  OutputPNG.SaveToFile('C:\output.png');

  InputPNG.Free;
  OutputPNG.Free;
  BMP.Free;
end;

How can I modify the code and preserve PNG transparency? Any solutions with free components such as Skia4Delphi are welcome.

3

There are 3 answers

1
Renate Schaaf On BEST ANSWER

Use a TWICImage to save to file. This will preserve the alpha-channel:

procedure SaveToPng(aBmp: TBitmap; const Filename: string);
var
  wic: TWICImage;
begin
  Assert(aBmp.PixelFormat=pf32bit);
  wic := TWICImage.Create;
  try
    aBmp.AlphaFormat := afDefined;
    wic.Assign(aBmp);
    wic.ImageFormat := wifPng;
    wic.SaveToFile(Filename);
  finally
    wic.Free;
  end;
end;

Be aware that whenever you use VCL.Graphics to assign a png to a bmp, the bitmap will have Alphaformat = afDefined, which means the RGB-channel is multiplied by alpha. If you now modify your bitmap's alphachannel this can lead to unexpected results. I would always set bmp.Alphaformat:=afIgnored before doing any modifications.

0
Garada On

Try to add this lines before assign the PNG image.

  BMP.PixelFormat := pf32bit; // not sure if this is necessary
  BMP.Transparent := True;
  BMP.Assign(iPNG);
1
dwrbudr On

Use the following code:

InputPNG.AssignTo(BMP);