一些GIF观众的Delphi TGIFImage动画问题 [英] Delphi TGIFImage animation issue with some GIF viewers

查看:1885
本文介绍了一些GIF观众的Delphi TGIFImage动画问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have discovered that animated GIFs created using Delphi 2009's TGIFImage sometimes doesn't play correctly in some GIF viewers. The problem is that the animation is restarted prematurely.

请考虑以下示例:

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.

(这是我找到的最简单的例子,展示了这个问题。)

(This is the simplest example I could find that exhibits the problem.)

输出是一个相当大的动画GIF。在Internet Explorer 11中,整个15秒的电影播放正常,但在Chrome浏览器中,电影在大约四秒钟之后就会过早重启。

The output is a rather large animated GIF. In Internet Explorer 11, the entire 15-second 'movie' is played properly, but in Google Chrome the 'movie' is prematurely restarted after only about four seconds.

为什么这是吗?


  1. 输出GIF文件是否有问题?

  2. 如果是,是上面的代码有什么问题,还是有一个问题,如果没有,这个问题的性质是什么??

  3. 在观众中?有多少可用观众有这个问题?有没有办法在GIF创建过程中避免这个问题?

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

For the benefit of the SO user, the above code is a minimal working example. Of course, I wasn't creating these psychedelic patterns when I discovered the issue. Instead, I was working on a Lorenz system simulator, and produced this GIF animation which does play in IE but not in Chrome:

显示问题的示例GIF动画http://privat.rejbrand.se/lorenz50.gif

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

In Internet Explorer 11, the model is rotated 360 degrees before the animation is restarted. In Google Chrome, the animation is restarted prematurely after only some 20 degrees.


  • Lorenz图片在互联网中的作品 Explorer 11.0.9600.17239,GIMP 2.8.0,Opera 12.16

  • Google Chrome 36.0.1985.143 m,Firefox 26.0,27.0中的Lorenz映像不起作用。 1,31.0。

  • The Lorenz image works in Internet Explorer 11.0.9600.17239, The GIMP 2.8.0, Opera 12.16
  • The Lorenz image does not work in Google Chrome 36.0.1985.143 m, Firefox 26.0, 27.0.1, 31.0.

如果我在GIMP中打开一个有问题的GIF,并让GIMP(重新)将其保存为动画GIF ,结果在每个观众中工作。以下是Lorenz动画的GIMPed版本:

If I open a 'problematic' GIF in The GIMP and let GIMP (re)save it as an animated GIF, the result works in every viewer. The following is the GIMPed version of the Lorenz animation:

示例GIF动画,已被GIMPed http://privat.rejbrand.se/lorenz50_GIMPed.gif

使用十六进制编辑器比较两个文件,并使用维基百科文章作为参考,似乎像NETSCAPE字符串在原来的错误的地方( unGIMPed)版本。这有点奇怪,即使我设置了GIF图像的 width height ,那么在逻辑屏幕描述符不存在。

Comparing the two files using a hex editor, and using the Wikipedia article as a reference, it seems, for instance, like the 'NETSCAPE' string is at the wrong place in the original (unGIMPed) version. It is somewhat strange, that even if I set the width and height of the GIF image, the corresponding values in the Logical Screen Descriptor are not there.

推荐答案

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

It's a bug in TGIFImage's LZW encoder.

在极少数情况下,LZW编码器将在LZW蒸汽末端输出一个额外的零字节。由于LZW结束块标记也是零字节,所以严格的GIF读取器可能会阻塞或将其解释为GIF的结尾(尽管文件标记的结尾为$ 3B)。

In some very rare circumstances the LZW encoder will output an extra zero byte at the end of the LZW steam. Since the LZW end block marker is also a zero byte, a strict GIF reader might choke on this or interpret it as the end of the GIF (although the end of file marker is $3B).

GIF读者可以处理这个问题的原因可能在于这个问题的GIF在很多年前是很常见的。显然,TGIFImage不是唯一可以做出特定错误的库。

The reason some GIF readers can handle this is probably that GIFs with this problem was common many years ago. Apparently TGIFImage wasn't the only library to make that particular mistake.

要解决问题,请对 gifimg.pas (更改标记为 * ):

To fix the problem make the following modification to gifimg.pas (change marked with *):

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;

这篇关于一些GIF观众的Delphi TGIFImage动画问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆