ImageMagick の例 --
アニメーションの最適化

目次
ImageMagick の例:序文と目次
最適化の概要
ImageMagick の汎用 GIF オプティマイザ
フレームの最適化
半透明の処理
色の最適化
圧縮の最適化
マイナーな最適化
GIF 最適化に関するその他の情報源
これらの例では、アニメーションの基本的な処理を使用して、アニメーションの最終的な表示とファイルサイズを最適化する方法を紹介します。これは、小さなサブフレームのオーバーレイを使用できる複雑な GIF アニメーションや、アニメーションの処理方法を制御する3種類の廃棄方法にとって特に重要です。

アニメーションの最適化の概要

アニメーションの最適化は容易ではありません。特に、色の制限があり、さまざまなフレーム廃棄手法を選択でき、小さな「サブフレーム」オーバーレイをフレーム間で使用できる GIF アニメーションは困難です。アニメーションを最適化する場合は、次の順序で最適化を試みる必要があります。ただし、これはこれらの最適化手法を検討する順序ではありません。GIF アニメーションの場合、フレームの最適化が最も基本的な最適化手法であり、最も効果が得られる部分です。そのため、最初に検討します。ユーザーが最も苦労する最適化の側面は、おそらく GIF アニメーションの色の制限による色の最適化でしょう。この側面の1つである単一のグローバルカラーテーブルは、GIF に保存する前の最後のステップとして実行する必要があります。そうしないと、演算子の効果が最終的な GIF ファイルの保存に失われる可能性があります。

ImageMagick の汎用 GIF オプティマイザ

-layers」メソッドの「Optimize」は、以下で詳しく説明するいくつかの手法を使用して、1つの合理的なステップで GIF アニメーションを最適化しようとします。現在、このオプションは(順番に)次の操作と同等です。この時点で、GIF アニメーションをすぐに保存できます。これらは、ほとんどのアニメーションシーケンスに適用できる、比較的安全な最適化手順ですが、GIF アニメーションが小さくなるという保証はありません。これは、透明度の最適化によって LZW 圧縮率が一般的に悪化する生のビデオシーケンスに特に当てはまります。ただし、漫画のような画像を含むほとんどの GIF アニメーションでは、「Optimize」演算子によって、適切に最適化されたアニメーションが生成されるはずです。ただし、この演算子はまだ開発中であり、将来的には次のような追加の標準最適化手順が含まれる可能性があります。
  • IM が通常 GIF ファイル形式で保存するときと同様に、アルファチャネルの 50% のしきい値を使用して、半透明のピクセルを削除します。必要に応じて、事前に半透明の処理を自分で行うこともできます。詳細については、GIF ブール値の透明度を参照してください。
  • ある種の色の最適化手法。正確な内容はまだ決定されておらず、アニメーションと含まれる色の数に応じて選択される場合があります。*ご意見をお待ちしております*。
  • 単一のグローバルカラーテーブル、「+map」操作。
つまり、「Optimize」は最終的に、IM ユーザーが迅速かつ簡単に使用できる IM 汎用 GIF アニメーションオプティマイザになることが期待されています。それまでは、特にスクリプトでは変更される可能性があるため、使用には注意してください。もちろん、多くの最適化手順は、特定のアニメーションでは労力に見合わない場合があります。また、このオプションはかなり遅くなる可能性があります。これが計画であり、この IM の例のセクションが目指している目標です。

フレームの最適化

フレームの最適化は、画像全体の完全なオーバーレイではなく、小さなサブ画像のオーバーレイに基づいています。これにより、明らかにピクセル数が少なくなり、ディスク上のファイルサイズが小さくなり、ネットワーク経由で送信されるデータ量が少なくなります。また、フレームのオーバーレイが小さくなると、クライアントコンピューターは画面上のピクセルを変更する作業をそれほど多く行う必要がなくなります。ただし、GIF 形式では、最後に表示されたフレームを処理するためにさまざまな廃棄方法を使用でき、それによってオーバーレイのサイズが異なる場合があります。それだけでなく、オーバーレイを複数の部分に分割したり、アクションを更新したりすることで、より複雑でありながらより最適化されたアニメーションを実現することも可能です。フレームの最適化は複雑なため、既存のフレームの最適化は通常、「-coalesce」操作を使用して最初に削除されます。連結の例を参照してください。当然のことながら、存在していた手動の最適化も削除されるため、注意が必要です。

基本的なフレームの最適化

-deconstruct」メソッドは、GIF アニメーションの基本的なフレーム最適化を実行します。ただし、前のセクションの分解の例で示したように、この演算子は、透明なピクセルが関係する場合、すべての GIF アニメーションで機能するわけではありません。具体的には、アニメーションで色のついたピクセルが透明にクリアされる場合です。つまり、オーバーレイアニメーションでのみ機能します。「-layers」メソッドの「OptimizeFrame」は、GIF フレームオプティマイザとして設計されており、GIF 廃棄方法を使用して、最小のサブフレームオーバーレイ画像を見つけようとします。結果は一般に混合廃棄アニメーションですが、特定のアニメーションに最適なソリューションであると判断された場合は、クリアされたフレームアニメーションまたは純粋なオーバーレイアニメーションが生成されることがよくあります。入力アニメーションは「*連結されたアニメーション*」である必要があるため、すべて同じサイズの完全な画像フレームのシーケンスで構成され、キャンバスのオフセットはありません。もちろん、連結されたアニメーションに既存の廃棄方法があっても、「OptimizeFrame」メソッドでは完全に無視されます。たとえば、前のセクションで作成した前のフレームを廃棄するアニメーションで試してみましょう。

  magick canvas_prev.gif -coalesce  -layers OptimizeFrame  optframe.gif
  gif_anim_montage optframe.gif optframe_frames.gif
[IM Output]
[IM Output] ==>
==> [IM Output]
ご覧のとおり、「-layers OptimizeFrame」は、前のフレームの廃棄を使用して、アニメーションを元のフレーム最適化された形式に正しく戻しました。この最適化は、処理が難しい背景を廃棄するアニメーションでも正しく機能します...

  magick canvas_bgnd.gif -coalesce  -layers OptimizeFrame  optframe_bgnd.gif
  gif_anim_montage optframe_bgnd.gif optframe_bgnd_frames.gif
[IM Output]
[IM Output]
アニメーションは、背景の廃棄を使用して完全にフレームが最適化されています。この演算子はすべての GIF アニメーションで正しく機能し、一般的に可能な限り最良の単純な「廃棄とフレームの最適化」を返します。
さて、IM が提供するものなど、あらゆる種類の単純なフレーム最適化に関する悪いニュースがあります。「OptimizeFrame」は、IM が理解できる特定のアニメーションに対して可能な限り最良のフレーム最適化を返しますが、うまく機能しない特殊なケースがいくつかあります。これらには以下が含まれます...
  • ピクセルのクリア(透明度への復帰)が必要なアニメーションですが、フレームのオーバーレイが大きすぎて、クリアする必要があるピクセルの小さな領域を効率的にクリアできない場合(以下の移動する穴のアニメーションを参照)。
  • 遠く離れた2つ以上の小さな変化領域を含むアニメーション。これらは実際には非常に一般的であり、フレームの最適化はひどいものです。(以下のフレーム更新の分割を参照)
  • 長期間(3フレーム以上)静的なままで、その後わずかに変化してから再び長期間静的なままである、非常に複雑な背景を持つアニメーションなど。このような複雑な状況で「最良の」フレーム最適化をコンピューターアルゴリズムが理解することはほぼ不可能です(つまり、何が静的な背景と見なされるべきでしょうか?)。このような場合、何が表示されているかを直感的に理解できる人間だけが、適切に最適化されたフレームオーバーレイシーケンスを生成できます。
*最適化が難しいアニメーションの例を求めています。ご協力ください。* IM が適切な最適化を生成できないアニメーションの例を見つけたら、さらに調査するために私にメールでお送りください。これは、新しい手法と可能な自動ソリューションを開発する方法です。私は当然、あなたの名前を貢献者として公開します。

ピクセルのオーバーレイなし- 1 フレームおきの画像の繰り返し

[アニメーション] 画像に最適な最適化は、ピクセルを全く重ねないことです!例えば、右側は nixscripter 氏によるシンプルなアニメーションです。フレームを見ると、あまり最適化されていないことが分かります。しかし、アニメーションの1秒ごとのフレームは単純に繰り返されていることに注目してください。

  gif_anim_montage paddleball.gif paddleball_frames.gif
[IM Output]
フレームの最適化後、非常に特殊な GIF ディスポーザルシーケンスが得られます。

  magick paddleball.gif -coalesce -layers OptimizeFrame  paddleball_opt.gif
  gif_anim_montage paddleball_opt.gif paddleball_opt_frames.gif
[IM Output]
[IM Output]
IM は元のフレームに重ねるのではなく、「以前」の GIF ディスポーザルを使用して最初の画像を復元することを選択しました。復元されたフレームはそのまま残されるため、変更されたピクセルはありません。そのため、サブフレームのオーバーレイは何も削減されません。残念ながら、IM も GIF 形式もサイズがゼロの画像を持つことは許可されていないため、代わりに特別な 1 つの透明ピクセルの最小画像が使用されます。「-crop」が実際の画像データを「ミス」して同じ結果を生成する場合にも広く使用されるため、この画像は ミス画像 として知られています。この画像は、実際には、ディスポーズメソッド時間遅延ループ反復 などのフレームのメタデータのみを保持します。「空」であっても、アニメーションの重要な部分です。そのため、最小限の単一の透明ピクセルを重ねることで、IM はこのアニメーションのスペース(と時間)を大幅に節約しました。

移動する穴のアニメーション- フレームの最適化が難しい

通常の最適化方法ではフレームの最適化があまりうまくいかない GIF アニメーションの極端なケースを次に示します。このアニメーションは基本的に、単純で変化のない背景画像で構成されていますが、その背景にはフレームごとに位置が変化する透明な「穴」があります。作成するには、レイヤーアルファ合成 を使用して、固定背景画像に穴を開けた、連結された画像シーケンスを作成する必要があります。また、「+antialias」スイッチを使用して、3 つの青と透明度の 4 色のみが使用されるようにしました。そのため、色の最適化の問題に対処する必要はありません。

  magick +antialias -size 100x100 -delay 100 xc:SkyBlue -loop 0 \
          -fill DodgerBlue -draw 'circle 50,50 15,25' \
          -fill RoyalBlue  -draw 'circle 50,50 30,25' \
          null: \( -size 100x100 xc:none -draw 'circle 40,25 27,22' \) \
                \( +clone -rotate 90 \) \( +clone -rotate 90 \) \
                \( +clone -rotate 90 \) -compose DstOut -layers Composite \
          -set dispose background  moving_hole.gif
  gif_anim_montage moving_hole.gif moving_hole_frames.gif
[IM Output]
[IM Output]
ご覧のとおり、アニメーションは機能し、丸い「穴」がこのページの背景色を表示し、[IM テキスト] バイトのサイズのアニメーションファイルを作成します。それでは、このアニメーションの簡単なフレーム最適化を試してみましょう。

  magick moving_hole.gif  -layers OptimizeFrame  moving_hole_opt.gif
  gif_anim_montage moving_hole_opt.gif moving_hole_opt_frames.gif
[IM Output]
[IM Output]
ちょっと待ってください、何も起こりませんでした!IM が達成できた最良の最適化は、まったく変更がないことでした!このアニメーションの上記の連結バージョンは、最も最適ですか?アニメーションの現状では... はい、これは純粋なフレームディスポーザル最適化によって達成できる最良の単純な最適化です!良くない。問題は、GIF アニメーションが前のフレームによって描画されたピクセルを「クリア」または「消去」するには、「背景」ディスポーズメソッドを使用する必要があることです。ただし、特別な状況では、「以前」のディスポーズメソッドを使用することもできます。ただし、「背景」ディスポーズは、オーバーレイされた領域のみをクリアできます。最初のフレームは画像全体の完全なオーバーレイであったため、画像全体がクリアされます。アニメーションの小さなセクションのみのピクセルをクリアする必要がある場合でもです。結果として、2 番目のフレームの大部分は、そのフレームのほとんどが以前に表示されていたとしても、オーバーレイする必要があります!この恐ろしいジレンマはアニメーションの残りの部分でも続き、基本的なフレームの最適化は行われません。このアニメーションはフレームの最適化が難しいと言いました。

フレームの倍増- 「穴」をフレーム最適化する方法

しかし、すべてが失われたわけではありません。アニメーションにいくつかの追加フレームを追加することにより、「OptimizeFrame」メソッドに、利用可能な GIF ディスポーズメソッドをより有効に活用するための余地を与えることができます。たとえば、ここでは最初の画像を 2 倍にすることで追加のフレームを追加しますが、アニメーションの全体的なタイミングが変わらないように、時間遅延をゼロにします。

  magick moving_hole.gif[0] -set delay 0   moving_hole.gif \
          -layers OptimizeFrame    moving_hole_dup.gif
  gif_anim_montage moving_hole_dup.gif moving_hole_dup_frames.gif
[IM Output]
[IM Output]
最初のフレームを 2 倍にすることで、アニメーションは [IM テキスト] バイトから [IM テキスト] バイトに削減されました。アニメーションには 5 つのフレームがありますが、サブフレーム画像オーバーレイのサイズが大幅に削減されたため、全体的なサイズがはるかに小さくなりました。2 倍にすることで、基本的に、ディスポーズメソッドのピクセルクリア機能と、次のフレームによって実行されるピクセルオーバーレイ機能が分離されます。ディスポーズとオーバーレイはどちらも GIF アニメーションプログラムによって同じフレーム更新の一部として行われるため、速度や品質の低下は目立ちません。これは複雑でトリッキーな手法であり、GIF アニメーションデザイナーや GIF 最適化プログラムではめったに見られず理解されていませんが、必要な場合はそのメリットは十分にあります。ただし、サブフレーム画像サイズの削減は短時間しか持続しません。後のフレームも次のフレームのピクセルをクリアする必要があるため、フレームは後のピクセルをクリアし続けるために再び大きくなります。つまり、ピクセルクリアは常にフレームを大きくし、小さくすることはありません。それでは、すべてのフレーム(2 倍にする必要のない最後のフレームを除く)を 2 倍にして、それが最終的な画像にどのように影響するかを見てみましょう...

  magick moving_hole.gif  \( -clone 0--1 -set delay 0 \) \
          +delete -insert 2 -insert 1 -insert 0 \
          -layers OptimizeFrame  moving_hole_double.gif
  gif_anim_montage x2 moving_hole_double.gif moving_hole_double_frames.gif
[IM Output]
[IM Output]
ご覧のとおり、フレーム数はほぼ 2 倍ですが、すべての画像サイズがはるかに小さく、[IM テキスト] バイトのサイズのアニメーションが生成されます。これは小さい結果ですが、最初に実行した単一フレームの 2 倍ほどではありません。「背景」フレームは前のフレームとまったく同じ複製であり、表示内容に変更はありません。ただし、次のフレーム画像がオーバーレイされる前にクリアする必要があるアニメーションの領域を定義します。次の「なし」フレームは、変更する必要があるピクセルと、前のフレームのディスポーズによってクリアされたピクセルを塗りつぶします。上記のアニメーションでは、それは新しい穴を形作るために必要なピクセルと、前の「穴」を埋めるために使用されたピクセルを意味します。結果は小さくなりますが、それほどではありません。追加のフレームには独自のコストがかかるためです。少なくとも、追加された各フレームにも独自の色テーブルがない場合、追加の色テーブルのサイズのために、このアニメーションは実際には大きくなっていたでしょう!

レイヤーの最適化プラス- 自動フレーム 2 倍最適化

バージョン 6.2.7 以降、IM は通常のフレーム最適化処理の一部として、フレームの 2 倍の最適化を自動的に実行できるようになりました。ただし、アニメーションを小さくするためにフレームを追加することは非常に根本的な変更であるため、独自の「-layers」メソッド「OptimizePlus」が与えられました。たとえば、IM にフレームの 2 倍の最適化を実行させましょう...

  magick moving_hole.gif  -layers OptimizePlus   moving_hole_oplus.gif
  gif_anim_montage x2 moving_hole_oplus.gif moving_hole_oplus_frames.gif
[IM Output]
[IM Output]
つまり、IM は前のフレームの 2 倍の例と同じ結果をもたらしました。したがって、GIF ファイルはまだ [IM テキスト] バイトのサイズです。ただし、「OptimizePlus」は、結果のアニメーション(3 フレーム)の現在と次のフレームのピクセル数が削減された場合にのみフレームを 2 倍にするため、IM にフレームを 2 倍にするかどうかを決定させることができます。「-layers」メソッド「OptimizePlus」は、フレームで最適化された GIF アニメーションを作成するときに追加のフレームを追加するため、最終的なアニメーションに変更を加えない不要なフレームや追加のフレームも削除します(必要に応じて遅延時間をマージします)。つまり、自動「RemoveDups」も実行します(次を参照)。「OptimizeFrame」メソッドはこれを行いません。

重複フレームの削除- 連続する重複画像のマージ

残念ながら、このアニメーションを連結すると、上記で追加されたすべての追加フレームも取得されます。

  magick moving_hole_oplus.gif -coalesce gif:- |\
     gif_anim_montage x2 - moving_hole_oplus_cframes.gif
[IM Output]
連結されたアニメーションからそのような不要な重複フレームを削除できるように、「RemoveDups」メソッドが提供されています。これは、アニメーションの各フレームを次のフレームと比較し、同じであれば最初のフレームを削除します(色の類似性は現在のファジー係数によって設定されます)。また、アニメーションのタイミングが失われないように、2 つのフレームのタイミング遅延もマージされます。例えば..

  magick moving_hole_oplus.gif -coalesce -layers RemoveDups  gif:- |\
     gif_anim_montage - moving_hole_oplus_rmdups_frames.gif
[IM Output]
これで、アニメーションの元の連結形式ができました。追加のフレームを削除する別の方法については、以下の「RemoveZero」メソッドを参照してください。

フレーム更新の分割- 2 つの離れた変更を個別に更新する

フレームの 2 倍化で見たように、「ピクセルのクリア」と新しいピクセルのオーバーレイを分離することにより、単一フレームオーバーレイの全体的なサイズを削減できます。ただし、このアニメーションはまだ非常に大きなオーバーレイを生成します。これは、ほとんどの場合、実際には 1 つのフレームから次のフレームに変更されないピクセルで構成されています。つまり、メインオーバーレイフレームは、互いにかなり離れている 2 つのかなり小さな領域のみを更新しているため、単一の大きなオーバーレイ画像が生成されます。2 つの変更を同時に更新しようとすると、2 つの領域間の変更されていないピクセルもすべて含まれるため、代わりに各領域を個別に更新します。つまり、変更された分離された領域ごとに、*フレームの更新を 2 つのフェーズに分割します*。この場合、最初に穴を埋め、次に新しい穴を別の更新として作成できます。どちらの個別の変更がどの順序で行われるかは実際には問題ありません(ディスポーザルに関しては可能ですが)、論理的に考える必要があります。また、ある変更が別の変更よりも簡単に作成できる場合もあります。たとえば、ここでは、古い穴を埋めるための追加のフレームを、新しい穴の「掘り」に対する別の更新として挿入します。これは、生成するのが最も簡単な中間フレームであり、アクションの最も論理的な順序です。もちろん、最後のフレームはアニメーションがループする前に破棄されるだけなので、これを行う必要はありません。

  magick moving_hole.gif \
          \( +antialias -size 100x100 -delay 0 xc:SkyBlue \
             -fill DodgerBlue -draw 'circle 50,50 15,25' \
             -fill RoyalBlue  -draw 'circle 50,50 30,25' \) \
          \( +clone \) -insert 1 \( +clone \) -insert 3  +swap \
          -set dispose background  moving_hole_split.gif
  gif_anim_montage x2 moving_hole_split.gif moving_hole_split_frames.gif
[IM Output]
[IM Output]
追加された中間フレームは、周囲のユーザー表示フレーム(時間遅延がゼロ以外のフレーム)とは異なることを覚えておいてください。これは単純な「フレームダブリング」ではなく、2つの離れた小さな変化を分離することです。この中間フレームの追加は、自動化できる単純な手順ではありません。これらの 中間フレームを生成するためのスマートなヒューリスティックを開発することは可能ですが、何をすべきか、ましてやそれを行うべきかどうかは必ずしも明らかではありません。そのようなヒューリスティックの生成を試みたい場合は、私にメールしてください。それでは、これらの追加フレームを追加した後に、標準のフレーム最適化を試してみましょう...

  magick moving_hole_split.gif \
               -layers OptimizeFrame     moving_hole_split_opt.gif
  gif_anim_montage x2 moving_hole_split_opt.gif \
                      moving_hole_split_opt_frames.gif
[IM Output]
[IM Output]
これらの「遅延ゼロの中間フレーム」を追加することで、このアニメーションフレームは、最適化されていない元のアニメーションよりも最適化され、[IM Text] バイトのアニメーションが生成されます。ただし、この特定のケースでは、自動化されたフレームダブリング手法(上記の「OptimizePlus」レイヤーメソッドを参照)を使用するほど効果的ではありません。ただし、「遅延ゼロの中間フレーム」を追加しても、その「フレームダブリング」手法も実行できなくなります...

  magick moving_hole_split.gif \
               -layers OptimizePlus moving_hole_split_oplus.gif
  gif_anim_montage x2 moving_hole_split_oplus.gif \
                      moving_hole_split_oplus_frames.gif
[IM Output]
[IM Output]
このアニメーションには、フレームの更新ごとに2つの追加の「遅延ゼロの中間フレーム」があります。1つ目は古い穴を埋め、2つ目は透明ピクセルを含む領域をクリアし、最後にクリアすべきでなかったピクセルを復元します。その結果、この特定の問題のアニメーションに対して可能な限り最適なフレーム最適化が実現し、最終ファイルサイズは[IM Text] バイトになります。つまり、4フレームのアニメーションは、6つの追加のゼロ時間遅延フレームを追加することで、サイズが小さくなりました!元のフレーム数の2倍以上です。奇妙ですが本当です!もちろん、GIFアニメーションプログラムが遅延ゼロの中間フレームを実際にあるがままに、つまりアニメーションの実際のフレーム間の中間更新として認識してくれると良いでしょう。しかし、それでも、更新が大きく分離され、非常に小さい場合、追加フレームによって引き起こされるわずかな一時停止はほとんど見えません。
もちろん、アニメーションの2つの分離された部分が実際には関連していない場合、それらを時間同期させる必要はありません。別の方法として、追加フレームを追加する代わりに、Webページに一緒に表示できる2つの完全に separate なアニメーションに分割することです。アニメーションの分割を参照してください。ただし、この特定のアニメーションは、時間的に分離した separate なアニメーションに分割することはできません。まず、離れた変更を時間同期する必要があります。次に、変更される4つの領域が水平方向と垂直方向の両方で重なります。これは、単純なHTMLの「テーブル」では、何らかのCSSのトリックを使わずに、サブアニメーションを完全な全体に再結合できないことを意味します。私の間違いを証明できますか? 今後:「アニメーション処理」の「2つの離れたオブジェクト」をアニメーション化するより良い例への参照。たとえば、2つの別々に移動するオブジェクトを含む。

遅延ゼロのフレームの削除- 中間更新の削除

もちろん、アニメーションからこれらの追加された中間フレームを削除し、実際にユーザーに一定期間表示されるフレームだけを残したい場合もあります。アニメーションを結合して「RemoveDups」メソッドを使用するだけでは不十分です。すべての中間フレームが周囲のフレームと類似しているわけではなく、重複していないためです。ただし、これらのタイプのフレームにはゼロ時間遅延があるため、別の特別な "-layers" メソッド「RemoveZero」を使用して、ゼロ時間遅延のフレームを削除できます。この同じメソッドは、フレームダブリングおよび「OptimizePlus」手法を使用して追加されたフレームも削除します。例えば...

  magick moving_hole_split_oplus.gif -coalesce -layers RemoveZero gif:- |\
     gif_anim_montage - moving_hole_split_rmzero_frames.gif
[IM Output]
これは、アニメーションをユーザーが表示可能なフレームのみに戻し、アニメーションを簡素化します。ゼロ時間遅延の中間フレームを削除した後、変更情報が失われているため、それらを再度追加することは非常に困難です。その結果、アニメーションはその後、フレームがうまく最適化されない可能性があります。最適化は、結局のところ、そのようなフレームの主な目的の1つです。

フレームの最適化結果と概要

移動する穴のアニメーションの最適化をまとめましょう...
[IM Text]
IMと人間の介入の助けを借りて、いくつかの複雑なフレーム処理を使用することで、「移動する穴」アニメーションを元のサイズのほぼ半分にフレーム最適化することができました。ただし、フレーム数は元の3倍弱です。もちろん、結果はアニメーションによって大きく異なりますが、フレームの最適化に使用した手法は同じです。人間の得意とする、少しの注意と事前の考慮が必要です。コンピューターは苦手です。
IMは、現在見ているフレームセットのピクセル数だけでなく、追加された追加フレームの全体サイズ、そしておそらく得られた全体的な圧縮結果も考慮して、画像のフレーム最適化方法を決定する必要があるという点があります。

一方、IMは、直接関係するフレームを超えて、結果として得られるピクセル数の節約も考慮していません。つまり、後のフレームサイズは、フレームのダブリング、または使用される廃棄方法の結果として、小さくなる可能性があります。これは、次のフレームですぐにではなく、アニメーションシーケンスの後半でピクセル数を大幅に削減できる「前の画像の廃棄」メソッドを使用するかどうかを選択する場合に特に当てはまります。ここで適切な選択を行うには、多くの場合、人間の入力が必要です。

そのため、IMが特定のアニメーションに対して最適な最適化の選択肢を生成することを保証することはできません。ただし、再帰を使用せずに、その選択を行うために、確かに良い試みを行っています。つまり、決定には直接のピクセル数のみを使用します。

再帰的アルゴリズム、つまり選択を行い、その選択から得られるアニメーションの最終的な最適サイズ(さらに再帰的な選択を含む)を確認するアルゴリズムは、保証された最適な最適化を生成できます。ただし、これは非常に低速な演算子になる可能性があり、大規模なアニメーションの場合、最終決定に何年もかかる可能性があります。また、最終結果に影響を与える可能性があるため、圧縮最適化の選択を含める必要があります。言い換えれば、このようなアルゴリズムは最適な最適化を保証できますが、計算コストが大きくなります。

もちろん、アニメーションが何を達成しようとしているのかを熟知している人間は、フレーム更新の分割で見たように、複雑なアニメーションでは一般的にうまくいきます。

再帰的なGIF最適化演算子の作成を試してみたい場合は、そうしてください。できる限りの方法でサポートします。市場に出回っている他のどのGIF最適化プログラムよりも優れているでしょう。また、ほとんどのGIFアニメーション開発者は、おそらくあなたの努力に非常に感謝するでしょう(金銭的に)。

半透明の処理

GIFファイル形式では、半透明ピクセルを使用できません(GIFブール値の透明度を参照)。これは事実であり、アニメーションを適切に最適化したり、GIF形式で保存したりする前に、アニメーションに適した方法で、存在する可能性のある半透明ピクセルを処理する必要があります。デフォルトでは、これらのピクセルを処理しない場合、IMは50%のしきい値を使用して、これらのピクセルを完全に透明または完全に不透明にします。ただし、これは必ずしも問題を処理する最良の方法ではない可能性があります。特に、シャドウエフェクトなど、半透明ピクセルの広い領域を含む画像ではそうです。たとえば、テレポートされるオブジェクトとしてほぼすべてのサブイメージを取ることができる、スターゲイトアースガードテレポートアニメーションを作成したかったのです。

  magick -channel RGBA -fill white \
          \( medical.gif -repage 100x100+34+65 -coalesce -set delay 200 \) \
          \( +clone -motion-blur 0x20+90 -blur 0x3 -colorize 100% \
                +clone -colorize 30%  +swap  -composite  -set delay 10  \) \
          \( +clone -roll +0-20 -blur 0x3 -colorize 30% \
             -motion-blur 0x15+90 -motion-blur 0x15-90 -set delay 10 \) \
          \( +clone -colorize 30% \
             -motion-blur 0x30+90 -blur 0x5 -crop +0+10\! \) \
          \( +clone -motion-blur 0x50+90 -blur 0x2 -crop +0+20\! \) \
          \( +page -size 100x100 xc:none -set delay 200 \) \
          -set dispose background -coalesce   -loop 0     teleport.miff
  gif_anim_montage teleport.miff teleport_frames.png
[IM Output]
元の画像が変更されずに保持されるように、アニメーションをIM内部MIFF:ファイル形式のままにして、PNG:ファイル形式を使用してフレームを表示し、含まれているすべての半透明ピクセルを確認できるようにしました!これは、半透明ピクセルを含むアニメーションだけでなく、多くの色を含むアニメーションにも重要です。画像シーケンスがGIFに保存されると、良好な色の最適化を生成する可能性は、良好から困難になります。
さて、アニメーションシーケンスがあります。これをGIFとして直接保存しようとすると、IMはそれらのすべての半透明ピクセルのしきい値を設定するだけです。

  magick teleport.miff teleport_thres.gif
  gif_anim_montage teleport_thres.gif teleport_thres_frames.gif
[IM Output]
[IM Output]
結果は、私たちが望んでいたものとはまったく異なります。デフォルトの50%の透明度の処理により、アニメーションは縮小する「卵」のように見えます。このアニメーションで実現したいものではありません..このタイプの透明度の処理が許容できる場合は、他の最適化を続行する前に、これを適用する方法です...

  magick teleport.miff -channel A -threshold 50% +channel \
                 ...do further processing now...       teleport.gif
上記のDIYを使用するもう1つの利点は、しきい値レベルを制御できることです。存在するほぼすべての半透明ピクセルを削除するには「10%」、すべてを不透明にするには「90%」と言います。

  magick teleport.miff -channel A -threshold 90% +channel teleport_thres90.gif
  gif_anim_montage teleport_thres90.gif teleport_thres90_frames.gif
[IM Output]
[IM Output]
しかし、このようなアニメーションにしきい値を適用することは、実現しようとしている透明効果を実際に損なうため、良い解決策ではありません。
上記のアニメーションのすべての特殊効果を維持するための最良の全体的な解決策は、単色の背景を追加することです。

  magick teleport.miff -bordercolor skyblue \
                  -coalesce -border 0 teleport_bgnd.gif
  gif_anim_montage teleport_bgnd.gif teleport_bgnd_frames.gif
[IM Output]
[IM Output]
これにより、アニメーションからすべての透明度が削除されますが、アニメーションが特定の背景色でのみ機能するという犠牲を払っています。ただし、特定のWebページ用にアニメーションを作成している場合は、まったく問題ありません。ただし、輪郭がはっきりした画像の場合、このようなディザパターンを使用すると、鋭いエッジに「ドット」の輪郭が生じる可能性があることに注意してください。そのため、一般的なケースにはお勧めしません。もう1つの解決策は、画像の半透明度を維持しようとするために、透明ピクセルと不透明ピクセルのパターンを生成しようとすることです。このため、IMは、この問題を解決できる幅広いディザオプションを提供しています。今後:透明度ディザリングに関するセクションを作成するためのリンク。たとえば、量子化とディザリング モノクロディザリングを使用したアルファチャネルの明白な最初の解決策は単純ではなく、おそらくいくつかの高度なマルチイメージ合成を正しく実行する必要があることに注意してください。
簡単な解決策は、拡散ピクセル順序ディザ手法を使用することです。これは、アルファチャネルのみに制限して、半透明ピクセルを削除できます。

  magick teleport.miff -channel A -ordered-dither o8x8  teleport_od.gif
  gif_anim_montage teleport_od.gif teleport_od_frames.gif
[IM Output]
[IM Output]
結果は妥当ですが、テレポートするオブジェクトではなく、溶解するオブジェクトのように見えます。
ハーフトーンを使用すると、透明度パターンをより大胆にすることで、はるかに優れた効果が得られます。

  magick teleport.miff -channel A -ordered-dither h8x8a teleport_htone.gif
  gif_anim_montage teleport_htone.gif teleport_htone_frames.gif
[IM Output]
[IM Output]
しかし、この特定のアニメーションでは、ユーザー設計のディザマップを使用して垂直線(水平線のディザパターンから)を作成すると、半透明ピクセルを削除しながらテレポートアニメーションを強化する効果が得られることがわかりました。

  magick teleport.miff -rotate 90 \
          -channel A -ordered-dither hlines -rotate -90 teleport_lines.gif
  gif_anim_montage teleport_lines.gif teleport_lines_frames.gif
[IM Output]
[IM Output]
ご覧のとおり、GIFアニメーションの半透明度を処理するには、かなりの数の可能性があります。

色の最適化

半透明ピクセルの処理は、GIFファイル形式の最初の制限にすぎません。次は、アニメーションの各カラーテーブルの256色の制限です。フレームごとに separate なカラーテーブルを使用できます。これは、1つのアニメーションに256色以上を使用できることを意味します。ただし、それでも必ずしも良い考えとは限りません。使用可能な色の最適化オプションの簡単な概要が必要な場合は、アニメーションの色の問題が最も深刻なビデオからGIFへの変換の例にジャンプすることをお勧めします。

GIF の色の問題

特にGIFアニメーションは色の扱いに問題があります。まず、半透明色を使用できず、フレームごとに256色、またはグローバルで256色の制限があります。さらに、あるフレームのピクセルに使用されている色が、画像のその部分が変化していない次のフレームで同じ色と一致しない限り、最良のフレーム最適化はうまく機能しません!これは簡単な問題のように思えるかもしれませんが、減色自体は非常に複雑な分野であり、IMの例では独自のセクション全体が必要でした。色の問題は、実際には、World Wide Web上で見られるほとんどのGIFアニメーションが漫画の種類であるか、または見栄えが悪い理由です。特に、アニメーションの大きなバージョンからサイズ変更された場合。 アニメーションのサイズ変更では、実際のサイズ変更プロセス自体よりも、色の最適化に多くの労力が必要になる可能性があります。ここでは、アニメーションの元のソースがあることを前提としています。しかし、これは常に可能とは限らないため、変更されたGIFアニメーションを最適化する場合は、特別な注意が必要になる場合があります。ただし、色が多すぎるアニメーションがある場合、最初に覚えておく必要があるのは...
GIF形式に直接保存しないでください。
MIFFファイル形式、または個別のPNG画像を使用してください。
GIFに保存するとすぐに、GIFの色の最適化の制御を失い、おそらくさまざまなフレーム最適化技術を使用してもうまく最適化されない、見栄えの悪いGIFアニメーションが作成されます。

高速アニメーション- 色が多すぎるアニメーション

まず、非常に多くの色を持つGIFアニメーションを生成して、色の最適化に伴う問題を実際にテストする必要があります。

  magick -dispose none -channel RGBA \
          \( medical.gif -repage 100x60+5+14  -coalesce -set delay 100 \) \
          \( medical.gif -repage 100x44+34+6  -coalesce -set delay 10 \
             -motion-blur 0x12+0  -motion-blur 0x12+180 -wave -8x200 \) \
          \( medical.gif -repage 100x60+63+14 -coalesce -set delay 100 \) \
          \( medical.gif -repage 100x44+34+6  -coalesce -set delay 10 \
             -motion-blur 0x12+0  -motion-blur 0x12+180 -wave +8x200 \) \
          null: \( +page  -size 120x15 xc:SkyBlue xc:RoyalBlue \
                   -size 120x70 gradient:SkyBlue-RoyalBlue \
                   +swap -append -blur 0x3 -background white -rotate -25 \
                \) -gravity center -compose DstOver -layers Composite \
          -loop 0   speed.miff

  magick  speed.miff  speed.gif
  gif_anim_montage  speed.gif  speed_frames.gif
[IM Output]
[IM Output]
アニメーションをGIF形式に直接保存するのではなく、最初にMIFF形式のファイル「speed.miff」に保存したことに注意してください。これにより、GIFメタデータ、タイミング遅延、および画像のすべての色など、元の作成(または変更)されたアニメーションのすべての側面が歪みなく保持されます。元のアニメーションを保存した後でのみ、元のアニメーションをGIF形式に直接変換しました。そうすることで、上記のコードが何を達成しようとしているのか、そしてなぜそれを「スピード」と呼んだのかを示すことができました。これはまた、研究と後の比較のためのベースラインGIFアニメーションを提供するためにも行われました。それでは、元のアニメーションのさまざまな詳細を見てみましょう。

  magick identify -format "Number of Frames: %n\n" speed.miff | head -1
[IM Text]

  magick identify -format "Colors in Frame %p: %k\n"  speed.miff
[IM Text]

  magick speed.miff +append  -format "Total Number of Colors: %k"  info:
[IM Text]
ご覧のとおり、アニメーションの各画像には非常に多くの色があります。各フレームの色数が異なるだけでなく、1 番目と 3 番目のフレームは、まったく同じではありませんが、色に関しては非常に似ています。ただし、GIFファイル形式はフレームごとに最大256色しか保存できないため、ImageMagickはこれをGIF形式で最も速く、最も愚かな方法で保存しました...アニメーションの各フレームの色数を減らしました(色量子化と呼ばれるプロセス)...

  magick identify -format "Colors in Frame %p: %k\n"  speed.gif
  magick speed.gif +append  -format "Total Number of Colors: %k"  info:
[IM Text]
各フレームの色数の減少がわずかに異なるため、IMはアニメーションの各フレームに個別のカラーマップを提供する必要もありました。これは、GIFファイルには常に1つの「グローバルカラーテーブル」がありますが、3つの個別の「ローカルカラーテーブル」もあることを意味します。「magick identify」コマンドでは、GIFファイルにそのようなローカルカラーテーブルがいくつあるかを知ることはできません。情報は形式に固有のものであり、IMが通常行う画像処理には重要ではないためです。ただし、より具体的な「Giftrans」プログラムでは、使用された低レベルのローカルカラーテーブルの数を調べることができます...

  giftrans -L speed.gif 2>&1 | grep -c "Local Color Table:"
[IM Text]
ご覧のとおり、このアニメーションには[IM Text]個のローカルカラーテーブルがあり、これは予測どおり、画像に存在するフレーム数よりも1つ少なくなっています。誤差補正ディザの問題で説明されているように、各フレームの色セットが異なるだけでなく、色のパターン(画像ディザパターン)もわずかに異なります。通常、IMのこのデフォルト操作である色量子化とディザリングは非常に優れており、写真、特に実際の生活の写真に最適です。実際、アニメーションの個々のフレームは一般的に見栄えがします。問題は、後で個別に減色されたフレームを単一のアニメーションシーケンスに連結しようとするときに発生します。

色の最適化の前にフレームの最適化を行うか?

上記のように、アニメーションをGIF形式に直接保存すると機能しますが、フレームごとにかなりの色の違いが生じます。これは、後のフレームの最適化に悪影響を及ぼします(後で説明します)。色の違いがそのような問題を引き起こさないようにするには、アニメーションを保存する前にフレームの最適化を実行し、フレーム間の色の違いの発生を防ぐことができます。ただし、色の削減前にフレームの最適化を行うと、色の削減のダイナミクスが変化することに注意してください。多くの場合、最適化されたサブフレームには静的な不動領域が表示されなくなります。つまり、そのフレームの色量子化では、それらの色の重要度が低くなり、色が少なくなります。

あいまいな色の最適化

ただし、GIF形式に保存される前の元のアニメーションにアクセスできない場合があります。これは、元のアニメーションをWWWからダウンロードした場合に特に当てはまります。つまり、すでにGIFの色の歪みがすべて存在するアニメーションがあり、後の最適化で問題が発生しています。フレームごとにわずかに異なる色のセットが使用され、アニメーションの各フレームに異なるピクセルパターンが使用されるため、各フレームは完全に異なる画像と見なすことができます。たとえば、同じ背景画像を大量に共有する最初のフレームと3番目のフレームを比較してみましょう。

  magick compare  speed.gif'[0,2]' speed_compare.gif
[IM Output]
上記の例の赤い領域は、予想どおり、異なる領域の2つの連続した正方形の領域を示しています。しかし、それはまた、2つのフレームの背景の輪郭を描く色の違いのバンドを示しています。これらは、まったく同じ背景を表すために異なる色のピクセルが使用された、背景グラデーションのエッジに沿った「チャーン」ディザパターンを表しています。これはまた、異なる色のセットとディザパターンを使用することによって引き起こされる背景の乱れが最も少ないフレームペアを示していました。実際の連続フレームの違いははるかに悪く、ほぼ連続した赤色の違いが生じます。
ソース画像がJPEG画像形式を使用して保存されていた場合、このような画像の違いも問題になります。この形式では、(品質が100%であっても)画像にわずかな色の違いが生じる非可逆圧縮方式が使用されます。ただし、違いは一般に、画像全体ではなく、実際の差分領域の周りのハローに限定されます。

言えることは、すべてのフレームの静的背景画像として1つの画像を使用する予定がない限り、アニメーションにJPEG画像を使用しないでくださいということです。
アニメーションの非常に多くのピクセルがフレームごとに異なるため、アニメーションをフレームの最適化しようとすると、まったく最適化されないのは当然です...

  magick speed.gif  -layers OptimizeFrame  speed_opt2.gif
  gif_anim_montage  speed_opt2.gif  speed_opt2_frames.gif
[IM Output]
ただし、アニメーションフレームの変更されていない部分間のピクセルの色の違いのほとんどは、実際にはかなり小さいです。そうでなければ、それはあまり良い減色ではありませんでした。つまり、IMに色の比較を少し緩めるように依頼することで、軽微な色の違いを無視するように依頼できます。これは、適切なファズ係数を設定することによって行われます。

  magick speed.gif  -fuzz 5%  -layers OptimizeFrame  speed_opt3.gif
  gif_anim_montage speed_opt3.gif speed_opt3_frames.gif
[IM Output]
小さなファズ係数を追加すると、IMはわずかに異なるピクセルを無視し、妥当なフレームの最適化を実現することがわかります。必要なファズ係数の量は、IMが元の画像の色の削減にどれだけの問題を抱えていたかによって異なります。この場合はそれほど多くないので、非常に小さな係数だけで済みました。小さなファズ係数で許容できる結果が得られる場合は、フレームの最適化透明度の最適化に設定してください。フレームごとに個別のカラーテーブルがあることを覚えておいてください。これは次の議論のポイントです。フレームの最適化では、2番目のフレームに「前の廃棄」を使用することにしたことに注意してください。つまり、2番目のフレームを表示した後、オーバーレイする前に画像を前のフレームの廃棄(最初の画像)に戻します。これにより、廃棄がまったく使用されなかった場合よりも、オーバーレイ画像のサイズが小さくなりました。 廃棄なしのみを使用した単純なオーバーレイアニメーションが必要な場合は、代わりに古い分解演算子(レイヤーCompareAnyとも呼ばれます)を使用して生成できます。

  magick speed.gif  -fuzz 5%  -deconstruct  speed_opt4.gif
  gif_anim_montage speed_opt4.gif speed_opt4_frames.gif
[IM Output]

単一のグローバルカラーテーブルの生成

すべてのフレームに異なる色のセットがあるため、IMは画像を保存せざるを得ませんでした。各フレームに個別のカラーテーブルがあります。最初のフレームには1つのグローバルカラーテーブル、後のフレームには3つのローカルカラーテーブルがあります。たとえば、ここでは非常に単純なプログラム「Giftrans」を使用して、いくつのフレームカラーテーブルが作成されたかを報告しました。

  giftrans -L speed.gif 2>&1 | grep -c "Local Color Table:"
[IM Text]
完全に合成された(またはフィルムストリップのような)アニメーションの場合、各フレームに個別のカラーテーブルを持つことは完全に問題なく合理的であり、そのような状況ではこれは問題ではありません。つまり、非常に異なる画像のスライドショーの場合、個別のカラーテーブルを使用すると、最も見栄えの良い結果が得られます。そのため、これはIMの通常の動作です。ただし、これらの追加のカラーテーブルはすべて、各カラーテーブルが大量のスペースを使用する可能性があるため、非常にコストがかかります。画像の各フレームで最大768バイト(256色×色あたり3バイト、つまり3/4キロバイト)です。それだけでなく、GIF圧縮はこれらのカラーテーブルを圧縮せず、ピクセルデータのみを圧縮します!個別のカラーテーブルにこれだけのファイルスペースを持つことが問題になる場合、特にほとんどのGIFアニメーションのように色が大きく変化しない画像の場合は、IMに必要なグローバルカラーテーブルのみを使用し、ローカルカラーテーブルを追加しないようにすることができます。 ---ローカルカラーマップを削除するには、すべての画像がパレットタイプになり、すべて同じパレットを使用する必要があります。コマンドラインでは、コマンドパレットを定義するために "-map image" を設定することでこれを行うことができます。 -colors は個々の画像に対して機能するため、使用できません。コマンドラインソリューションは、すべての画像に追加される共通パレットへのグローバルカラーリダクションを実行する特別な "+map" オプションです。画像への変更はパレットを無効にする可能性があるため、カラーリダクションはGIFフレームおよび/または圧縮の最適化を行う*前*に行う必要がありますが、共通パレットは保存の直前、最後に行う必要があります。"+map" が画像の色数を減らす必要がない場合は、色を減らしたりディザリングしたりせず、すべての画像に共通パレットを追加するだけです。 --- IMは、すべてのフレームが同じカラーパレットを使用する場合、単一のグローバルカラーテーブルを生成できます。IMでは、カラーパレットは、そのようなパレットを使用している画像形式から読み込むか、"-map" カラーリダクション演算子を使用して割り当てることによってのみ画像に割り当てられます。詳細については、定義済みカラーマップによるディザを参照してください。この単一のカラーテーブルを生成する1つの方法は、単にすべてのフレームを "-append" し、"-colors" コマンドを使用して色数を最小セット(256未満、またはさらに小さいカラーテーブルが必要な場合はそれより小さい)に減らすことです。結果のカラーテーブルは、"-map" を使用して元の画像に適用できます。たとえば、ここでは画像を64色の一つのセットに減らします。これは、特別なMPRインメモリレジスタを使用して、生成されたカラーマップを "-map" コマンドに割り当てます。

  magick speed.gif \
          \( -clone 0--1 -background none +append \
              -quantize transparent  -colors 63  -unique-colors \
             -write mpr:cmap    +delete \) \
          -map mpr:cmap      speed_cmap.gif
[IM Output]
"Giftrans" を使用して結果のアニメーションを調べると、画像がフレームごとに個別のカラーテーブルではなく、単一の「グローバル」カラーテーブルを使用していることがわかります。
画像を一緒に追加する前に「None」の「-background」色を使用します。これにより、合成されていないアニメーションでこれを使用でき、不要な色が追加される可能性がありません。

特別な "-quantize" 設定の「transparent」色空間は、IMがカラーマップに半透明色を生成しようとしないようにするために使用されました。半透明を処理できないGIFに結果を保存しているので、無駄なことです。

最後に、透明色のためのスペースを残すために、63色に色を減らします。アニメーションによっては透明性が必要なものもあれば、このアニメーションのように、後で圧縮最適化のために透明性が必要になる場合もあります。
これを簡単にするために、IMはすべてのフレームに共通のカラーマップ(256色)を生成し、グローバルに適用する特別なオプション "+map" も提供しています。これは、上記のDIYメソッドよりもはるかに簡単です。

  magick speed.miff  -alpha off +map   speed_map.gif
[IM Output]
これにより、結果の画像に[IM Text]の「ローカル」(または不要な)カラーテーブルができました。次の最適化セクションでは、単一カラーテーブルバージョンのアニメーションを使用しますが、実際にはアニメーションの最適化のどの時点でも、特に最終保存の前に行うことができます。カラーテーブルの最適化の結果、直接変換されたGIFで[IM Text]バイトだったアニメーションは、 "+map" 演算子を使用した後、[IM Text]バイトになりました。アニメーションのフレーム(および「ローカルカラーテーブル」)が多いほど、節約量が多くなります。アニメーションを変更すると、一般的に各画像の保存されたパレットが削除されるため、 "+map" 演算子はアニメーションをGIFに保存する前の最後の操作であることが重要です。覚えておいてください
ローカルカラーマップの削除は、GIF形式で保存する前の最後の最適化である必要があります。

順序付きディザ、「静的」の削除

建設中
ただし、これまでに見てきたすべてのテクニックでは、すべてがオーバーレイごとに変化するディザパターンを持つ可能性があることに注意してください。テレビの砂嵐のように見えるピクセルのチャーンです。
... small number of colors ...
小さな動かない領域のフレーム最適化を使用すると、さらに見苦しい静的な長方形領域を取得することさえできます。...順序付きディザ...今のところ、より実用的で詳細の少ないビデオからGIFへの最適化の概要を参照してください。

圧縮の最適化

半透明ピクセルを処理し、色とフレームの最適化を使用してアニメーションをGIF形式で保存すると、GIF圧縮アルゴリズムに対応することで、ファイルサイズをさらに小さくすることができます。GIFファイル形式で使用できるLZW圧縮またはランレングス圧縮は、一定色の大きな領域、または何度も繰り返されるピクセルシーケンスが見つかった場合、よりよく圧縮されます。

透明度の最適化

フレームの最適化で見たように、オーバーレイされた画像は、多くの場合、すでに表示されているものを繰り返しているだけです。つまり、GIF廃棄方法が適用された後にすでに存在する同じ色のピクセルをオーバーレイしています。しかし、なぜこれらのピクセルを繰り返す必要があるのでしょうか。すでに画像で透明性を使用している場合は、透明ピクセル色を使用できます。ただし、これらの領域を透明に変換すると、均一な透明ピクセルの領域が大きくなります。これは、オーバーレイされている同じ領域に一致するために必要なさまざまな色を使用するよりも、圧縮率が向上します。たとえば、単純なフレーム最適化オーバーレイアニメーションを次に示します...
[IM Output] [IM Output]
表示結果を変更しないピクセルをすべて透明度に置き換えるために、「-layers」メソッド「OptimizeTransparency」(IM v6.3.4-4で追加)を使用してみましょう。

  magick bunny_bgnd.gif -layers OptimizeTransparency \
                                    +map   bunny_bgnd_opttrans.gif
  gif_anim_montage bunny_bgnd_opttrans.gif bunny_bgnd_opttrans_frames.gif
[IM Output]
[IM Output]
ご覧のとおり、サブフレームには大きな透明領域があり、最終的なアニメーションには影響しません。ピクセルを変更する必要がある領域はまだオーバーレイされていますが、変更されない領域は透明になっています。アニメーション化されているオブジェクト内にも含まれており、かなりひどい「穴」が残っています。大きな一定の透明色の領域は(理論的には)圧縮率が向上するため、結果の「乱雑な」アニメーションははるかに小さくなり、フレーム最適化結果のファイルサイズが[IM Text]バイトから[IM Text]バイトに減少します。これは、非常に小さな労力に対して非常に大きな節約です。最適化方法は合成アニメーションである必要はなく、サブフレームのサイズは変更されないため、これ以降のフレームの廃棄のニーズが維持されることに注意してください。そのため、節約はアニメーション内の同じピクセル数の圧縮率の向上に過ぎず、ファイルに保存される実際のピクセル数ではありません。したがって、必要なフレームの最適化が完了した後、最終的な最適化手順の1つとして実行する必要があります。
FUTURE: link to a 'remove background' from animation
もちろん、他のほとんどの「-layers」メソッド(比較または最適化)と同様に、ファジー係数を指定して、「どの程度類似しているか」色を調整できます。これにより、色のディザリングが不十分なアニメーションを処理できますが、上記の色の最適化を学習していれば、その問題は発生しません。無料のアニメーションGIFツール「InterGIF」も、上記と同じタイプの透明度圧縮最適化を提供しますが、「ファジー係数」もサポートして「近い」色の変化を透明にする機能はありません。IMが使用できない場合の代替手段としてのみお勧めします。

LZW の最適化- (IM以外)

一部のアプリケーションでは、アニメーション内の画像の圧縮率をさらに最適化して、さらに小さくすることができます。ただし、これを行うには、GIF画像形式で一般的に使用されるLZW圧縮に関する専門的な知識が必要です。基本的に、特定のピクセルシーケンスがLZW圧縮アルゴリズムによってすでに処理されている場合、それらを透明ピクセルに変換することはありません。なぜなら、そうすることで画像の圧縮が向上しないからです。奇妙に聞こえますが、 funktioniertです。残念ながら、*ImageMagickはこれを行いません*。これは、一般的なケースで良好な結果を生み出すための適切なヒューリスティックを得るために、非常に多くのスキルとリソースを必要とする複雑なプロセスであるためです。ただし、「-O2」の最高最適化レベルで「Gifsicle」アプリケーションを使用して、この手法の実用的な例を示すことができます。

  gifsicle -O2 bunny_bgnd.gif -o bunny_bgnd_lzw_gifsicle.gif
  gif_anim_montage bunny_bgnd_lzw_gifsicle.gif bunny_bgnd_lzw_frames.gif
[IM Output]
[IM Output]
LZW圧縮最適化により、単純な透明度最適化で画像が[IM Text]バイトから「Gifsicle」で[IM Text]バイトに削減されました。大きな改善ではありません。ただし、より重要な側面は、LZW最適化では変更されていないピクセルが透明に変換されますが(上記の透明度の最適化で行ったように)、アニメーション内で既に表示されているピクセルシーケンスは変更されなかったことです。つまり、アニメーション内で*まだ*繰り返されていないピクセルグループのみが変更されました。これらのピクセルは(おそらく)LZW圧縮パターンを使用してすでにうまく圧縮されているためです。繰り返されるピクセルパターンを生成するために、どのピクセルを透明にするかを選択することは非常に複雑で難しく、正確なLZW実装にも依存する可能性があることに注意してください。これはヒューリスティックであり、完全に予測可能なアルゴリズムではありません。そのため、異なるプログラムは、圧縮される特定の画像に応じて、一般的に異なる結果を生成します。あるプログラムはある画像の圧縮率が優れている場合があり、別のプログラムは別の画像の圧縮率が優れている場合があります。

非可逆 LZW の最適化- (IM以外)

別の圧縮改善方法では、ピクセル自体の色をわずかに変更して「近い色のマッチ」にすることで、画像内の色参照の繰り返しを増やします。繰り返されるパターンは当然圧縮率が向上するため、より高い圧縮率を実現できます。以前の「Gifsicle」アプリケーションのフォークであるgiflossyも、「gifsicle」プログラムを生成しますが、画像をわずかに変更する(「非可逆」)オプションがあり、GIF画像、特にアニメーションのサイズをさらに削減できます。

  gifsicle -O3 --lossy=80 bunny_bgnd.gif -o bunny_bgnd_giflossy.gif
  gif_anim_montage bunny_bgnd_giflossy.gif bunny_bgnd_lossy_frames.gif
[IM Output]
[IM Output]

作成日:2007年3月22日(「アニメーション」の小区分)
更新日: 2007年4月23日
著者: Anthony Thyssen, <Anthony.Thyssen@gmail.com>
生成に使用したImageMagickのバージョン: [バージョン画像]
URL: https://imagemagick.dokyumento.jp/Usage/anim_opt/
これにより、サイズは [IM テキスト] となり、驚異的な1/3のサイズ削減となりました。ただし、この方法では結果として得られる画像が変更されるため、最適化は非可逆圧縮となり、微妙な色の情報が失われる可能性があります。その反面、フレーム間の最適化ではなく、個々のフレームを圧縮することができます。ここでは、例えば、以前の非可逆LWZ圧縮と可逆LWZ圧縮の差分画像を生成しました。

  magick compare bunny_bgnd_lossy_frames.gif bunny_bgnd_lzw_frames.gif \
          bunny_bgnd_diff_frames.gif
[IM Output]
ご覧のとおり、色の変更はほとんどすべて、漫画のウサギではなく、元の「草」の背景画像で行われました。基本的に、大きな違いを生むのにちょうどいい程度にわずかに変更を加えただけで、この画像では見た目に大きな違いはありません。もちろん、色量子化とディザリング自体は非可逆圧縮の操作であり、通常は必要となるため、GIF画像やGIFアニメーションに非可逆圧縮方式を使用することは、それほど悪いとは見なされていません。
Photoshopで使用するために特許を取得したこのようなアルゴリズムの別の例としては、米国特許7031540 - 視覚的な歪みを最小限に抑えながら画像のLempel-Ziv圧縮率を高めるための変換をご覧ください。内容は難解ですが、より良い圧縮を実現するために使用される方法が詳細に説明されています。

順序付きディザ LZW の最適化

ディザリング処理は通常、LZW最適化よりも非可逆圧縮の処理であるため、より良い解決策は、繰り返されるパターンをディザリング処理の一部として導入することです。順序付きディザリングを使用することで、このようなパターンを生成し、これまでのすべてのLZW最適化方法よりもはるかに強力なLZW圧縮を実現できます。さらに、静的な背景を持つ実際のアニメーションのフレーム最適化も改善できます。背景を人工的にクリーンアップして、変化しない静的な背景にする場合は特に効果的です。もちろん、順序付きディザ圧縮最適化は、以前にディザリングまたはその他の色の最適化が行われていない画像に対してのみ機能します。そのため、GIF画像形式用にまだ最適化されていないアニメーションに対してのみ機能します。また、現在、IMの順序付きディザは、均一なカラーパレットに対してのみ機能します。IMには、「最適な色」または「ユーザー指定」のパレットを実装した順序付きディザはまだありませんが、非常に限定された(固定された)カラーパレットにそのようなアルゴリズムを使用するプログラムを見たことがあります。*そのようなアルゴリズムをご存知ですか?* 順序付きディザを使用してLZW圧縮最適化を改善する実際的な例については、順序付きディザビデオを参照してください。

その他のLZW最適化

画像内の「ディザパターン」を再配置することで、LZW最適化をさらに改善することもできます。また、一部のGIFツールはまさにそれを実行できます。ただし、このような最適化は、微妙ですが不適切な色の変化が生じる可能性があるため、常に人の目で確認する必要があります。

圧縮最適化の概要

圧縮最適化を使用して実現された最終的なファイルサイズの完全な概要を以下に示します。
[IM Text]
ご覧のとおり、非常に複雑なLZW最適化を使用しても、組み込みの透過性最適化に比べて、最終的なアニメーションサイズにわずかな改善しか見られませんでした。ただし、結果は、利用可能な多くのGIF最適化アプリケーションプログラムと、最適化されている特定のアニメーションによって大きく異なります。ファイルサイズから最後のバイトまで取得する必要がある場合は、LZW最適化が必要なものかもしれません。また、本当に最高の結果が必要な場合は、特定のアニメーションをより適切に圧縮するプログラム(およびヒューリスティック実装)をいくつか試して、他の最適化機能が提供されているかどうかを確認する必要があります。通常、透過性最適化はほとんどの目的に十分です。LZW最適化はわずかに良い結果しか得られず、ディスクストレージサイズではなく、ネットワーク伝送サイズをわずかに節約します。後者はより大きな「チャンク」または「ブロック」のストレージを使用するためです。このため、LZW最適化はやり過ぎだと感じており、労力や費用(これらのツールのほとんどは商用販売されています)に見合う価値がないと考えています。
残念ながら、これらのGIFオプティマイザは、すべてのタイプの事前最適化されたアニメーションをうまく処理できるわけではないことがわかりました。

たとえば、テストでは、「Gifsicle」は、「背景廃棄」手法を使用してすでに最適化されているアニメーションを処理できないことが示されています。

一方、「InterGIF」は、初期キャンバスと「以前の廃棄」手法を使用するようにすでに最適化されているアニメーションを処理しません。また、IMが現在提供している透過性最適化の使用に限定されています。

したがって、あるユーティリティの出力を別のユーティリティにフィードすることによって、GIF最適化ユーティリティを混在させないことをお勧めします。少なくとも、以前のフレームの最適化を削除するためにアニメーションを合体させずに、混在させないでください。

IM、Gifsicle、InterGIFはすべて、独自の最適化を削除するための合体オプションを提供していますが、IM以外のアプリケーションがすべてのアニメーションを正しく合体させることを保証することはできません。IMは保証します。

これらのプログラムは、IMの高度なフレーム最適化手法(さまざまなGIF廃棄手法を自動的に選択して切り替えます)では確実に使用できないため、IMはこれらのLZW圧縮オプティマイザを使用するだけよりも全体的に優れた結果を生成することがよくあります。また、後で結果を合体させて、そのフレームを最適化されていない元のアニメーションと比較して、IM以外のプログラムがアニメーションを完全に台無しにしていないことを確認することをお勧めします(上記の注記を参照)。本当に起こることなので、スクリプトはアニメーションが有効なままであることを再確認する必要があります。
このタイプの最適化に関する別のチュートリアル(Windowsツールを使用)は、WebReferenceフレーム最適化です。サイトの名前は間違っており、圧縮最適化に関するものであることに注意してください。

マイナーな最適化

GIFアニメーションで使用できる、あまりにも明白でしばしば見落とされる最適化手法がいくつかあります。
  • GIFコメントを削除します。
    多くのGIFアニメーションには、大きなテキストコメントが追加されています。多くの場合、これらはグラフィックエディタによって広告の一種として自動的に追加されました。たとえば、「Gimp」はデフォルトで画像に「The GIMPで作成」を追加します。コメントが必要ない場合は、スペースの無駄です。IMの「magick」コマンドにGIFを保存する前に「+set comment」演算子を追加して、コメントを削除します。ただし、コメントが著作権表示である場合は、法的理由から削除しない方がよい場合があります。
  • 色の数を減らします。
    アニメーションがより少ない色で問題ない場合は、より小さいカラーテーブルを使用します。カラーテーブルは常に2の累乗であるため、32色未満を使用できる場合は、256色を使用するよりもはるかに小さくなります。カラーテーブルはGIF画像データに使用されるLZW圧縮では圧縮されないため、これは特に重要です。また、一般的に、色の数が少ないほど、共通のピクセルシーケンスが見つかるため、LZW圧縮が向上します。ただし、色のディザリング(色の削減による)によって圧縮が悪化する可能性もあるため、これは常に当てはまるとは限りません。ここで、ディザリングをオフにするか、順序付きディザを使用することが重要になる場合があります。
  • ユーザーに見えるフレーム数を半分にします。
    スムーズさが低いアニメーションを処理できる場合は、フレームの総数を半分にすることで、最終的なファイルサイズを大幅に改善できます。もちろん、ファイルサイズが半分になるわけではなく、アニメーションの品質は低下します。しかし、ファイルサイズを大幅に削減できます。
  • アニメーションをトリミング/サイズ変更します。
    画像サイズが小さいほど、ファイルサイズが小さくなります。したがって、大きなアニメーションが必要ない場合は、大きなアニメーションを使用しないでください。リストでは、大きなアニメーションやビデオを表す小さなサムネイルの方が、実際のアニメーションやビデオよりも適していることがよくあります。
  • 代替圧縮。
    アニメーションをアニメーションとして使用しない予定の場合、つまり、単に保存したい場合は、LZW圧縮をオフにして、ファイル全体を「gzip」または「bzip2」で圧縮して保存します。結果ははるかに小さくなりますが、クライアントブラウザで直接使用できるようにするには、Webサーバーがブラウザに適切な「コンテンツ」と「圧縮」のヒントを提供する必要があります。「Apache」Webサーバーはデフォルトではこれを行いませんが、実行するように設定できます。さらに良いのは、圧縮されていないアニメーションのディレクトリ全体を単一のファイルにアーカイブして、ストレージの圧縮をさらに向上させることです。
他に最適化のアイデアがあれば、お知らせください。

GIF最適化に関するその他の情報源

以上で、アニメーションを処理するためのさまざまな基本的な方法とテクニックの説明は終わりです。ただし、全体像を把握するには、次のIMの例ページに進み、実際の画像のアニメーションで発生する実際の問題を処理するためのテクニックについて詳しく説明します。また、上記の多くのテクニックは、ビデオからGIFへの最適化の実際的な例で示されています。GIFアニメーションの処理に真剣に取り組んでいる場合は、色量子化についてもよく読んでおくことをお勧めします。色の削減は、GIFアニメーションを適切に処理するための鍵となることがよくあります。WWWで見つけたGIFアニメーション最適化手法に関するその他の役立つ情報源には、次のようなものがあります。ここにリストする必要があるページがあると思われる場合は、メールでお知らせください。有用なコンテンツのページのみを追加するため、リンクを追加する保証はありません。