11

Delphi 2009 を使用して作成されたアニメーション GIF が、一部のGIF ビューアTGIFImageで正しく再生されないことがあることを発見しました。問題は、アニメーションが時期尚早に再開されることです。

次の例を検討してください。

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 では、「ムービー」はわずか 4 秒ほどで途中で再開されます。

どうしてこれなの?

  1. 出力された GIF ファイルに何か問題がありますか?
  2. もしそうなら、上記の私のコードに何か問題がありますか、それとも問題がありGIFImgますか?
  3. そうでない場合、ビューアの問題の性質は何ですか? 利用可能な視聴者のうち、この問題を抱えている割合は? GIF の作成中にこの問題を「回避」する方法はありますか?

SO ユーザーの利益のために、上記のコードは最小限の作業例です。もちろん、この問題を発見したとき、私はこれらのサイケデリックなパターンを作成していませんでした。代わりに、私は Lorenz システム シミュレーターに取り組んでいて、IE では再生されますが Chrome では再生されない次の GIF アニメーションを作成しました。

問題を表示するサンプル GIF アニメーション

Internet Explorer 11 では、アニメーションが再開される前にモデルが 360 度回転します。Google Chrome では、わずか 20 度でアニメーションが途中で再開されます。

  • ローレンツ画像Internet Explorer 11.0.9600.17239、GIMP 2.8.0、Opera 12.16 で動作します
  • ローレンツ画像は、Google Chrome 36.0.1985.143 m、Firefox 26.0、27.0.1、31.0 では動作しません。

GIMP で「問題のある」GIF を開き、GIMP にアニメーション GIF として (再) 保存させると、結果はすべてのビューアで機能します。以下は、ローレンツ アニメーションの GIMP バージョンです。

GIMP されたサンプル GIF アニメーション

16 進エディターを使用して 2 つのファイルを比較し、ウィキペディアの記事を参照として使用すると、たとえば、'NETSCAPE' 文字列が元の (GIMP されていない) バージョンの間違った場所にあるように見えます。widthGIF 画像のandを設定してもheight、Logical Screen Descriptor に対応する値が存在しないのは少し奇妙です。

4

2 に答える 2

1

編集:これは答えではないことが判明しましたが、ループ拡張に関するルールが引き続き適用されるため、そのままにしておきます。


NETSCAPE ループ拡張は、最初の拡張でなければなりません。

var
  Frame: TGIFFrame;
...
for i := 0 to 499 do
begin
  MakeFrame(i);
  Frame := g.Add(bm);
  if (i = 0) then
    TGIFAppExtNSLoop.Create(Frame).Loops := 0;
  TGIFGraphicControlExtension.Create(Frame).Delay := 3;
  Writeln('Creating frame ', i+1, ' of 500.');
end;

参照: TGIFImage FAQ .

それ以外は、GIF に問題はありませんが、グローバル カラー テーブルを使用してサイズを少し小さくすることができます。

于 2014-08-25T06:59:30.810 に答える