加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 无法在动态创建的TBitmap上绘制GIF

发布时间:2020-12-15 09:47:53 所属栏目:大数据 来源:网络整理
导读:我想提取GIF图像的帧.下面的代码有效,但它不是我需要的.我需要将提取的帧保存在一系列位图中. procedure TForm1.Button2Click(Sender: TObject);var GIF: TGIFImage; Bitmap: TBitmap; I: Integer; GR: TGIFRenderer; R: TRect;begin GIF := TGIFImage.Creat
我想提取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,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);

         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,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;

解决方法

TCustomGIFRenderer.Draw检查要渲染的画布.如果它与它从上次渲染中记住的那个不同(并且它不同,因为您为每个帧创建了新的位图),则调用TCustomGIFRenderer.Reset方法,正如其名称所解释的那样,重置帧索引这就是为什么你总是只渲染第一帧的原因.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读