使用GifImage从gif提取帧

问题描述 投票:0回答:1

如何使用没有TGifRenderer的GifImage 2.X从gif提取帧?

这是我尝试的方法,但是帧不完整(半空白):

  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

    Bmp.Assign(Gif.Images.SubImages[i].Bitmap);

    Bmp.SaveToFile('out/' + IntToStr(i) + '.bmp');

  end;
delphi delphi-7 gif delphi-2010 delphi-6
1个回答
0
投票

这是2.X版的解决方案,可以从http://www.tolderlund.eu/delphi/下载大梁框架可以设置各种处置方法。下面的方法不支持此方法,但是对于大多数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;

不同的解决方案是使用TGIFPainter,但是它将无法循环使用。

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;

而且3.X版的解决方案非常简单:

  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;
© www.soinside.com 2019 - 2024. All rights reserved.