This is a solution for version 2.X available for download from http://www.tolderlund.eu/delphi/ Gir frames can have various disposal methods set. The approach below doesn't support this but it works fine for most GIFS.
Gif := TGifImage.Create; Gif.LoadFromFile('test.gif'); Bmp := TBitmap.Create; Bmp.PixelFormat := pf24bit; Bmp.Width := Gif.Width; Bmp.Height := Gif.Height; for i:=0 to Gif.Images.Count-1 do begin if GIF.Images[i].Empty then Continue; //skip empty Gif.Images[i].Bitmap.TransparentColor := Gif.Images[i].GraphicControlExtension.TransparentColor; if i <> 0 then Gif.Images[i].Bitmap.Transparent := True; //you should also take care of various disposal methods: //Gif.Images[i].GraphicControlExtension.Disposal Bmp.Canvas.Draw(0,0, Gif.Images[i].Bitmap); Bmp.SaveToFile('out/' + IntToStr(i) + '.bmp'); end;
A different solution is to use TGIFPainter but then it won't work in a loop.
Bmp: TBitmap; //global ... Gif := TGifImage.Create; Gif.LoadFromFile('test.gif'); Gif.DrawOptions := GIF.DrawOptions - [goLoop, goLoopContinously, goAsync]; Gif.OnAfterPaint := AfterPaintGIF; Gif.Paint(Bmp.Canvas, Bmp.Canvas.ClipRect, GIF.DrawOptions); ... procedure TForm1.AfterPaintGIF(Sender: TObject); begin if not (Sender is TGIFPainter) then Exit; if not Assigned(Bmp) then Exit; Bmp.Canvas.Lock; try Bmp.SaveToFile('out/' + IntToStr(TGIFPainter(Sender).ActiveImage) + '.bmp'); finally Bmp.Canvas.Unlock; end; end;
And the solution for version 3.X is super easy:
Gif := TGifImage.Create; Gif.LoadFromFile('test.gif'); Bmp := TBitmap.Create; Bmp.PixelFormat := pf24bit; Bmp.Width := Gif.Width; Bmp.Height := Gif.Height; GR := TGIFRenderer.Create(GIF); GR.Animate := True; for i:=0 to Gif.Images.Count-1 do begin if GIF.Images[i].Empty then Continue; //skip empty GR.Draw(Bmp.Canvas, Bmp.Canvas.ClipRect); GR.NextFrame; Bmp.SaveToFile('out/' + IntToStr(i) + '.bmp'); end;
TGIFImagedoes not have anImages.SubImages[]property, it should beImages.Frames[]instead, eg:Gif.Images.Frames[i].Bitmap