Search code examples
delphipnggifalpha-transparency

delphi convert gif to png with transparency


I am trying to convert a gif to png, that's easy, but the problem is the result image is not transparent, also I would like to have in the png image the alpha channel.

This is my code:

procedure TForm1.Button1Click(Sender: TObject);
var
png: TPngImage;
 p : TPicture;
begin
 p := TPicture.Create;
 p.LoadFromFile('C:\temp\php.gif');
 png := TPngImage.CreateBlank(COLOR_RGB , 8, p.Width, p.Height);
 png.Canvas.Draw(0,0, p.Graphic);
 png.SaveToFile('C:\Windows\Temp\test.png');
end;

The new picture has the background black, should be transparent.

If I try to add the ALPHA in the constructor, is 100% transparent.

png := TPngImage.CreateBlank(COLOR_RGBALPHA , 8, p.Width, p.Height);

Solution

  • Just by drawing GIF image on PNG canvas will not move transparency information from GIF image to PNG. You will have to do it yourself.

    ForceAlphaChannel procedure will create alpha channel for any PNG image based on given TransparentColor.

    procedure ForceAlphaChannel(Image: TPngImage; BitTransparency: Boolean; TransparentColor: TColor; Amount: Byte);
    var
      Temp: TPngImage;
      x, y: Integer;
      Line: VCL.Imaging.PngImage.pByteArray;
      PixColor: TColor;
    begin
      Temp := TPngImage.CreateBlank(COLOR_RGBALPHA, 8, Image.Width, Image.Height);
      try
        for y := 0 to Image.Height - 1 do
          begin
            Line := Temp.AlphaScanline[y];
            for x := 0 to Image.Width - 1 do
              begin
                PixColor := Image.Pixels[x, y];
                Temp.Pixels[x, y] := PixColor;
                if BitTransparency and (PixColor = TransparentColor) then Line^[x] := 0
                else Line^[x] := Amount;
              end;
          end;
        Image.Assign(Temp);
      finally
        Temp.Free;
      end;
    end;
    

    If you add call to ForceAlphaChannel after you have drawn GIF image you will get transparency based on transparent color you define.

    procedure TForm1.Button1Click(Sender: TObject);
    var
    png: TPngImage;
     p : TPicture;
     TransparentColor: TColor;
    begin
     p := TPicture.Create;
     p.LoadFromFile('C:\temp\php.gif');
     TransparentColor := clFuchsia;
     png := TPngImage.CreateBlank(COLOR_RGB , 8, p.Width, p.Height);
     // set png background color to same color that will be used for setting transparency
     png.Canvas.Brush.Color := TransparentColor;
     png.Canvas.FillRect(rect(0, 0 , p.Width, p.Height));
     png.Canvas.Draw(0, 0, p.Graphic);
     ForceAlphaChannel(png, true, TransparentColor, 255);
     png.SaveToFile('C:\Windows\Temp\test.png');
    end;