我想提取 GIF 图像的帧。下面的代码有效,但这不是我需要的。我需要将提取的帧保存在一系列位图中。
procedure TForm1.Button2Click(Sender: TObject);
var
  GIF: TGIFImage;
  Bitmap: TBitmap;
  I: Integer;
  GR: TGIFRenderer;
  R: TRect;
begin
  GIF := TGIFImage.Create;
  TRY
    GIF.LoadFromFile('c:\1.gif');
    Bitmap := TBitmap.Create;       <------------ one single object, reused
    Bitmap.SetSize(GIF.Width, GIF.Height);
    GR := TGIFRenderer.Create(GIF);
    try
      for I := 0 to GIF.Images.Count - 1 do
       begin    
         GR.Draw(Bitmap.Canvas, Bitmap.Canvas.ClipRect);
         Self.Canvas.Draw(0, 0, Bitmap);
         GR.NextFrame;
       end;
    finally
      GR.Free;
    end;
  finally
    GIF.Free;
    //Bitmap.Free;
  end;
end;
所以我为每一帧动态创建一个位图。但这行不通。它只会在所有位图中显示相同/第一帧!
procedure TForm1.Button2Click(Sender: TObject);
var
  GIF: TGIFImage;
  Bitmap: TBitmap;
  I: Integer;
  GR: TGIFRenderer;
  R: TRect;
begin
  GIF := TGIFImage.Create;
  TRY
    GIF.LoadFromFile('c:\1.gif');
    GR := TGIFRenderer.Create(GIF);
    try
      for I := 0 to GIF.Images.Count - 1 do
       begin
         Bitmap := TBitmap.Create;       <----- multiple bitmaps, one for each frame
         Bitmap.SetSize(GIF.Width, GIF.Height);
         GR.Draw(Bitmap.Canvas, Bitmap.Canvas.ClipRect);
         Self.Canvas.Draw(0, 0, Bitmap);
         GR.NextFrame;
       end;
    finally
      GR.Free;
    end;
    {TODO: store bitmaps in a TObjectList for later use 
    List.Add(Bitmap);  }     
  finally
    GIF.Free;
  end;
end;
上面这段代码有什么问题?也许 TGIFRenderer 只绘制帧之间的差异?
更新 TLama/jachguate:
TLama 说代码不起作用,因为我没有释放位图。我不想释放位图。我以后需要它们。这是一些(演示级)代码。
VAR List: TObjectList;    {used and freed somwhere else}
procedure TForm1.Button2Click(Sender: TObject);
var
  GIF: TGIFImage;
  UniqueBMP: TBitmap;
  I: Integer;
  GR: TGIFRenderer;
  R: TRect;
begin
  List:= TObjectList.Create;
  GIF := TGIFImage.Create;
  TRY
    GIF.LoadFromFile('c:\1.gif');
    GR := TGIFRenderer.Create(GIF);
    try
      for I := 0 to GIF.Images.Count - 1 do
       begin
         UniqueBMP := TBitmap.Create;
         UniqueBMP.SetSize(GIF.Width, GIF.Height);
         if GIF.Images[I].Empty then Break;
         GR.Draw(UniqueBMP.Canvas, UniqueBMP.Canvas.ClipRect);
         Self.Canvas.Draw(0, 0, UniqueBMP);
         Sleep(50);
         List.Add(UniqueBMP);
         GR.NextFrame;
       end;
    finally
      GR.Free;
    end;
  finally
    GIF.Free;
  end;
end;
procedure TForm1.btnFreeClick(Sender: TObject);
begin 
  FreeAndNil(List);
end;