gpt4 book ai didi

Delphi TGIFImage 动画问题与某些 GIF 查看器有关

转载 作者:行者123 更新时间:2023-12-03 14:40:29 25 4
gpt4 key购买 nike

我发现使用 Delphi 2009 的 TGIFImage 创建的动画 GIF 有时无法在某些 GIF 查看器中正常播放。问题是动画过早地重新启动。

考虑以下示例:

program GIFAnomaly;

{$APPTYPE CONSOLE}

uses
Windows, Types, Classes, SysUtils, Graphics, GIFImg;

var
g: TGIFImage;
bm: TBitmap;

procedure MakeFrame(n: integer);
var
x: Integer;
y: Integer;
begin
for x := 0 to 256 - 1 do
for y := 0 to 256 - 1 do
bm.Canvas.Pixels[x, y] := RGB((x + n) mod 255,
(x + y - 2*n) mod 255, (x*y*n div 500) mod 255);
end;

var
i: integer;

begin

bm := TBitmap.Create;
bm.SetSize(256, 256);

g := TGIFImage.Create;
g.Animate := true;
for i := 0 to 499 do
begin
MakeFrame(i);
TGIFGraphicControlExtension.Create(g.Add(bm)).Delay := 3;
Writeln('Creating frame ', i+1, ' of 500.');
end;
TGIFAppExtNSLoop.Create(g.Images.Frames[0]).Loops := 0;

g.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\test.gif');


end.

(这是我能找到的显示问题的最简单的示例。)

输出是一个相当大的动画 GIF。在 Internet Explorer 11 中,整个 15 秒的“电影”可以正常播放,但在 Google Chrome 中,“电影”仅在大约四秒后就过早重新启动。

这是为什么?

  1. 输出的 GIF 文件有问题吗?
  2. 如果是这样,我上面的代码是否有问题,或者 GIFImg 有问题?
  3. 如果不是,查看器中问题的本质是什么?有多少观众有这个问题?有没有办法在 GIF 创建过程中“避免”这个问题?

为了 SO 用户的利益,上面的代码是一个最小的工作示例。当然,当我发现这个问题时,我并没有创造这些迷幻的模式。相反,我正在开发 Lorenz 系统模拟器,并制作了这个 GIF 动画,它可以在 IE 中播放,但不能在 Chrome 中播放:

Sample GIF animation displaying the issue

在 Internet Explorer 11 中,模型会在动画重新启动之前旋转 360 度。在 Google Chrome 中,动画仅在大约 20 度后就过早重新启动。

  • Lorenz 图像在 Internet Explorer 11.0.9600.17239、GIMP 2.8.0、Opera 12.16 中工作
  • Lorenz 图像在 Google Chrome 36.0.1985.143 m、Firefox 26.0、27.0.1、31.0 中不起作用

如果我在 GIMP 中打开一个“有问题”的 GIF 并让 GIMP(重新)将其另存为动画 GIF,则结果在每个查看器中都有效。以下是洛伦兹动画的 GIMP 版本:

Sample GIF animation that has been GIMPed

使用十六进制编辑器比较两个文件,并使用 the Wikipedia article作为引用,例如,“NETSCAPE”字符串似乎位于原始(未GIMPed)版本中的错误位置。有点奇怪的是,即使我设置了 GIF 图像的宽度和高度,逻辑屏幕描述符中的相应值也不存在。

最佳答案

这是 TGIFImage 的 LZW 编码器中的一个错误。

在某些非常罕见的情况下,LZW 编码器将在 LZW 流末尾输出额外的零字节。由于 LZW 结束 block 标记也是一个零字节,严格的 GIF 阅读器可能会对此感到窒息或将其解释为 GIF 的结束(尽管文件结束标记是 $3B)。

一些 GIF 阅读器能够处理这个问题的原因可能是很多年前就有这个问题的 GIF 很常见。显然 TGIFImage 并不是唯一犯这个错误的库。

要解决此问题,请对 gifimg.pas 进行以下修改(用 * 标记的更改):

procedure TGIFWriter.FlushBuffer;
begin
if (FNeedsFlush) then
begin
FBuffer[0] := Byte(FBufferCount-1); // Block size excluding the count
Stream.WriteBuffer(FBuffer, FBufferCount);
FBufferCount := 1; // Reserve first byte of buffer for length
FNeedsFlush := False; // *** Add this ***
end;
end;

关于Delphi TGIFImage 动画问题与某些 GIF 查看器有关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25476193/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com