delphidelphi-10.3-rioskiaskia4delphi

PNG to TBitmap (preserving transparency)


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.


Solution

  • 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.