使用 GifImage 从 gif 中提取帧
Extract a frame from a gif using GifImage
如何使用没有 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;
这是版本 2.X 的解决方案,可从 http://www.tolderlund.eu/delphi/ 下载
Gir 框架可以设置各种处理方法。下面的方法不支持这一点,但它适用于大多数 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;
如何使用没有 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;
这是版本 2.X 的解决方案,可从 http://www.tolderlund.eu/delphi/ 下载 Gir 框架可以设置各种处理方法。下面的方法不支持这一点,但它适用于大多数 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;