ImageMagick の例 --
アニメーションの最適化
- 目次
-
ImageMagick の例:序文と目次
-
最適化の概要
-
ImageMagick の汎用 GIF オプティマイザ
-
フレームの最適化
- 基本的なフレームの最適化
- ピクセルのオーバーレイなし - 1 フレームおきの画像の繰り返し
- 移動する穴のアニメーション - フレームの最適化が難しいアニメーション
- フレームの倍増
- レイヤーの最適化プラス
- 重複フレームの削除
- フレーム更新の分割
- 遅延ゼロのフレームの削除
- フレームの最適化結果と概要
-
半透明の処理
-
色の最適化
- GIF の色の問題
- 高速アニメーション - 色が多すぎるアニメーション
- 色の最適化の前にフレームの最適化を行うべきか?
- あいまいな色の最適化
- 単一のグローバルカラーテーブル
- 色のディザリング
-
圧縮の最適化
-
マイナーな最適化
-
GIF 最適化に関するその他の情報源
アニメーションの最適化の概要
アニメーションの最適化は容易ではありません。特に、色の制限があり、さまざまなフレーム廃棄手法を選択でき、小さな「サブフレーム」オーバーレイをフレーム間で使用できる 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
」メソッドでは完全に無視されます。たとえば、前のセクションで作成した前のフレームを廃棄するアニメーションで試してみましょう。
|
![]() |
||
![]() ![]() ![]() ![]() |
-layers OptimizeFrame
」は、前のフレームの廃棄を使用して、アニメーションを元のフレーム最適化された形式に正しく戻しました。この最適化は、処理が難しい背景を廃棄するアニメーションでも正しく機能します...
|
![]() |
||
![]() |
さて、IM が提供するものなど、あらゆる種類の単純なフレーム最適化に関する悪いニュースがあります。「
OptimizeFrame
」は、IM が理解できる特定のアニメーションに対して可能な限り最良のフレーム最適化を返しますが、うまく機能しない特殊なケースがいくつかあります。これらには以下が含まれます...- ピクセルのクリア(透明度への復帰)が必要なアニメーションですが、フレームのオーバーレイが大きすぎて、クリアする必要があるピクセルの小さな領域を効率的にクリアできない場合(以下の移動する穴のアニメーションを参照)。
- 遠く離れた2つ以上の小さな変化領域を含むアニメーション。これらは実際には非常に一般的であり、フレームの最適化はひどいものです。(以下のフレーム更新の分割を参照)
- 長期間(3フレーム以上)静的なままで、その後わずかに変化してから再び長期間静的なままである、非常に複雑な背景を持つアニメーションなど。このような複雑な状況で「最良の」フレーム最適化をコンピューターアルゴリズムが理解することはほぼ不可能です(つまり、何が静的な背景と見なされるべきでしょうか?)。このような場合、何が表示されているかを直感的に理解できる人間だけが、適切に最適化されたフレームオーバーレイシーケンスを生成できます。
ピクセルのオーバーレイなし- 1 フレームおきの画像の繰り返し
![[アニメーション]](../images/paddleball.gif)
フレームの最適化後、非常に特殊な GIF ディスポーザルシーケンスが得られます。
|
![]() |
||
![]() |
-crop
」が実際の画像データを「ミス」して同じ結果を生成する場合にも広く使用されるため、この画像は ミス画像 として知られています。この画像は、実際には、ディスポーズメソッド、時間遅延、ループ反復 などのフレームのメタデータのみを保持します。「空」であっても、アニメーションの重要な部分です。そのため、最小限の単一の透明ピクセルを重ねることで、IM はこのアニメーションのスペース(と時間)を大幅に節約しました。移動する穴のアニメーション- フレームの最適化が難しい
通常の最適化方法ではフレームの最適化があまりうまくいかない GIF アニメーションの極端なケースを次に示します。このアニメーションは基本的に、単純で変化のない背景画像で構成されていますが、その背景にはフレームごとに位置が変化する透明な「穴」があります。作成するには、レイヤーアルファ合成 を使用して、固定背景画像に穴を開けた、連結された画像シーケンスを作成する必要があります。また、「+antialias
」スイッチを使用して、3 つの青と透明度の 4 色のみが使用されるようにしました。そのため、色の最適化の問題に対処する必要はありません。![[IM テキスト]](moving_hole_size.txt.gif)
|
![]() |
||
![]() |
フレームの倍増- 「穴」をフレーム最適化する方法
しかし、すべてが失われたわけではありません。アニメーションにいくつかの追加フレームを追加することにより、「OptimizeFrame
」メソッドに、利用可能な GIF ディスポーズメソッドをより有効に活用するための余地を与えることができます。たとえば、ここでは最初の画像を 2 倍にすることで追加のフレームを追加しますが、アニメーションの全体的なタイミングが変わらないように、時間遅延をゼロにします。
|
![]() |
||
![]() |
![[IM テキスト]](moving_hole_size.txt.gif)
![[IM テキスト]](moving_hole_dup_size.txt.gif)
|
![]() |
||
![]() |
![[IM テキスト]](moving_hole_double_size.txt.gif)
背景
」フレームは前のフレームとまったく同じ複製であり、表示内容に変更はありません。ただし、次のフレーム画像がオーバーレイされる前にクリアする必要があるアニメーションの領域を定義します。次の「なし
」フレームは、変更する必要があるピクセルと、前のフレームのディスポーズによってクリアされたピクセルを塗りつぶします。上記のアニメーションでは、それは新しい穴を形作るために必要なピクセルと、前の「穴」を埋めるために使用されたピクセルを意味します。結果は小さくなりますが、それほどではありません。追加のフレームには独自のコストがかかるためです。少なくとも、追加された各フレームにも独自の色テーブルがない場合、追加の色テーブルのサイズのために、このアニメーションは実際には大きくなっていたでしょう! レイヤーの最適化プラス- 自動フレーム 2 倍最適化
バージョン 6.2.7 以降、IM は通常のフレーム最適化処理の一部として、フレームの 2 倍の最適化を自動的に実行できるようになりました。ただし、アニメーションを小さくするためにフレームを追加することは非常に根本的な変更であるため、独自の「-layers
」メソッド「OptimizePlus
」が与えられました。たとえば、IM にフレームの 2 倍の最適化を実行させましょう...
|
![]() |
||
![]() |
![[IM テキスト]](moving_hole_oplus_size.txt.gif)
-layers
」メソッド「OptimizePlus
」は、フレームで最適化された GIF アニメーションを作成するときに追加のフレームを追加するため、最終的なアニメーションに変更を加えない不要なフレームや追加のフレームも削除します(必要に応じて遅延時間をマージします)。つまり、自動「RemoveDups
」も実行します(次を参照)。「OptimizeFrame
」メソッドはこれを行いません。 重複フレームの削除- 連続する重複画像のマージ
残念ながら、このアニメーションを連結すると、上記で追加されたすべての追加フレームも取得されます。連結されたアニメーションからそのような不要な重複フレームを削除できるように、「RemoveDups
」メソッドが提供されています。これは、アニメーションの各フレームを次のフレームと比較し、同じであれば最初のフレームを削除します(色の類似性は現在のファジー係数によって設定されます)。また、アニメーションのタイミングが失われないように、2 つのフレームのタイミング遅延もマージされます。例えば..
magick moving_hole_oplus.gif -coalesce -layers RemoveDups gif:- |\ gif_anim_montage - moving_hole_oplus_rmdups_frames.gif |
![[IM Output]](moving_hole_oplus_rmdups_frames.gif)
RemoveZero
」メソッドを参照してください。 フレーム更新の分割- 2 つの離れた変更を個別に更新する
フレームの 2 倍化で見たように、「ピクセルのクリア」と新しいピクセルのオーバーレイを分離することにより、単一フレームオーバーレイの全体的なサイズを削減できます。ただし、このアニメーションはまだ非常に大きなオーバーレイを生成します。これは、ほとんどの場合、実際には 1 つのフレームから次のフレームに変更されないピクセルで構成されています。つまり、メインオーバーレイフレームは、互いにかなり離れている 2 つのかなり小さな領域のみを更新しているため、単一の大きなオーバーレイ画像が生成されます。2 つの変更を同時に更新しようとすると、2 つの領域間の変更されていないピクセルもすべて含まれるため、代わりに各領域を個別に更新します。つまり、変更された分離された領域ごとに、*フレームの更新を 2 つのフェーズに分割します*。この場合、最初に穴を埋め、次に新しい穴を別の更新として作成できます。どちらの個別の変更がどの順序で行われるかは実際には問題ありません(ディスポーザルに関しては可能ですが)、論理的に考える必要があります。また、ある変更が別の変更よりも簡単に作成できる場合もあります。たとえば、ここでは、古い穴を埋めるための追加のフレームを、新しい穴の「掘り」に対する別の更新として挿入します。これは、生成するのが最も簡単な中間フレームであり、アクションの最も論理的な順序です。もちろん、最後のフレームはアニメーションがループする前に破棄されるだけなので、これを行う必要はありません。
|
![]() |
||
![]() |
|
![]() |
||
![]() |
![[IM Text]](moving_hole_split_opt_size.txt.gif)
|
![]() |
||
![]() |
![[IM Text]](moving_hole_split_oplus_size.txt.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]](moving_hole_split_rmzero_frames.gif)
フレームの最適化結果と概要
移動する穴のアニメーションの最適化をまとめましょう... 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]](teleport_frames.png)
さて、アニメーションシーケンスがあります。これをGIFとして直接保存しようとすると、IMはそれらのすべての半透明ピクセルのしきい値を設定するだけです。
|
![]() |
magick teleport.miff -channel A -threshold 50% +channel \ ...do further processing now... teleport.gif |
上記のDIYを使用するもう1つの利点は、しきい値レベルを制御できることです。存在するほぼすべての半透明ピクセルを削除するには「10% 」、すべてを不透明にするには「90% 」と言います。
|
![]() |
上記のアニメーションのすべての特殊効果を維持するための最良の全体的な解決策は、単色の背景を追加することです。
|
![]() |
簡単な解決策は、拡散ピクセル順序ディザ手法を使用することです。これは、アルファチャネルのみに制限して、半透明ピクセルを削除できます。
|
![]() |
ハーフトーンを使用すると、透明度パターンをより大胆にすることで、はるかに優れた効果が得られます。
|
![]() |
しかし、この特定のアニメーションでは、ユーザー設計のディザマップを使用して垂直線(水平線のディザパターンから)を作成すると、半透明ピクセルを削除しながらテレポートアニメーションを強化する効果が得られることがわかりました。
|
![]() |
色の最適化
半透明ピクセルの処理は、GIFファイル形式の最初の制限にすぎません。次は、アニメーションの各カラーテーブルの256色の制限です。フレームごとに separate なカラーテーブルを使用できます。これは、1つのアニメーションに256色以上を使用できることを意味します。ただし、それでも必ずしも良い考えとは限りません。使用可能な色の最適化オプションの簡単な概要が必要な場合は、アニメーションの色の問題が最も深刻なビデオからGIFへの変換の例にジャンプすることをお勧めします。GIF の色の問題
特にGIFアニメーションは色の扱いに問題があります。まず、半透明色を使用できず、フレームごとに256色、またはグローバルで256色の制限があります。さらに、あるフレームのピクセルに使用されている色が、画像のその部分が変化していない次のフレームで同じ色と一致しない限り、最良のフレーム最適化はうまく機能しません!これは簡単な問題のように思えるかもしれませんが、減色自体は非常に複雑な分野であり、IMの例では独自のセクション全体が必要でした。色の問題は、実際には、World Wide Web上で見られるほとんどのGIFアニメーションが漫画の種類であるか、または見栄えが悪い理由です。特に、アニメーションの大きなバージョンからサイズ変更された場合。 アニメーションのサイズ変更では、実際のサイズ変更プロセス自体よりも、色の最適化に多くの労力が必要になる可能性があります。ここでは、アニメーションの元のソースがあることを前提としています。しかし、これは常に可能とは限らないため、変更されたGIFアニメーションを最適化する場合は、特別な注意が必要になる場合があります。ただし、色が多すぎるアニメーションがある場合、最初に覚えておく必要があるのは...
GIF形式に直接保存しないでください。
MIFFファイル形式、または個別のPNG画像を使用してください。
GIFに保存するとすぐに、GIFの色の最適化の制御を失い、おそらくさまざまなフレーム最適化技術を使用してもうまく最適化されない、見栄えの悪いGIFアニメーションが作成されます。 MIFFファイル形式、または個別のPNG画像を使用してください。
高速アニメーション- 色が多すぎるアニメーション
まず、非常に多くの色を持つGIFアニメーションを生成して、色の最適化に伴う問題を実際にテストする必要があります。
|
![]() |
||
![]() |
speed.miff
」に保存したことに注意してください。これにより、GIFメタデータ、タイミング遅延、および画像のすべての色など、元の作成(または変更)されたアニメーションのすべての側面が歪みなく保持されます。元のアニメーションを保存した後でのみ、元のアニメーションをGIF形式に直接変換しました。そうすることで、上記のコードが何を達成しようとしているのか、そしてなぜそれを「スピード」と呼んだのかを示すことができました。これはまた、研究と後の比較のためのベースラインGIFアニメーションを提供するためにも行われました。それでは、元のアニメーションのさまざまな詳細を見てみましょう。
|
![]() |
|
![]() |
|
![]() |
|
![]() |
magick identify
」コマンドでは、GIFファイルにそのようなローカルカラーテーブルがいくつあるかを知ることはできません。情報は形式に固有のものであり、IMが通常行う画像処理には重要ではないためです。ただし、より具体的な「Giftrans
」プログラムでは、使用された低レベルのローカルカラーテーブルの数を調べることができます...ご覧のとおり、このアニメーションには![[IM Text]](speed_ctables.txt.gif)
色の最適化の前にフレームの最適化を行うか?
上記のように、アニメーションをGIF形式に直接保存すると機能しますが、フレームごとにかなりの色の違いが生じます。これは、後のフレームの最適化に悪影響を及ぼします(後で説明します)。色の違いがそのような問題を引き起こさないようにするには、アニメーションを保存する前にフレームの最適化を実行し、フレーム間の色の違いの発生を防ぐことができます。ただし、色の削減前にフレームの最適化を行うと、色の削減のダイナミクスが変化することに注意してください。多くの場合、最適化されたサブフレームには静的な不動領域が表示されなくなります。つまり、そのフレームの色量子化では、それらの色の重要度が低くなり、色が少なくなります。あいまいな色の最適化
ただし、GIF形式に保存される前の元のアニメーションにアクセスできない場合があります。これは、元のアニメーションをWWWからダウンロードした場合に特に当てはまります。つまり、すでにGIFの色の歪みがすべて存在するアニメーションがあり、後の最適化で問題が発生しています。フレームごとにわずかに異なる色のセットが使用され、アニメーションの各フレームに異なるピクセルパターンが使用されるため、各フレームは完全に異なる画像と見なすことができます。たとえば、同じ背景画像を大量に共有する最初のフレームと3番目のフレームを比較してみましょう。
|
![]() |
![]() ![]() |
ソース画像がJPEG画像形式を使用して保存されていた場合、このような画像の違いも問題になります。この形式では、(品質が100%であっても)画像にわずかな色の違いが生じる非可逆圧縮方式が使用されます。ただし、違いは一般に、画像全体ではなく、実際の差分領域の周りのハローに限定されます。 言えることは、すべてのフレームの静的背景画像として1つの画像を使用する予定がない限り、アニメーションにJPEG画像を使用しないでくださいということです。 |
magick speed.gif -layers OptimizeFrame speed_opt2.gif gif_anim_montage speed_opt2.gif speed_opt2_frames.gif |
![[IM Output]](speed_opt2_frames.gif)
magick speed.gif -fuzz 5% -layers OptimizeFrame speed_opt3.gif gif_anim_montage speed_opt3.gif speed_opt3_frames.gif |
![[IM Output]](speed_opt3_frames.gif)
magick speed.gif -fuzz 5% -deconstruct speed_opt4.gif gif_anim_montage speed_opt4.gif speed_opt4_frames.gif |
![[IM Output]](speed_opt4_frames.gif)
単一のグローバルカラーテーブルの生成
すべてのフレームに異なる色のセットがあるため、IMは画像を保存せざるを得ませんでした。各フレームに個別のカラーテーブルがあります。最初のフレームには1つのグローバルカラーテーブル、後のフレームには3つのローカルカラーテーブルがあります。たとえば、ここでは非常に単純なプログラム「Giftrans
」を使用して、いくつのフレームカラーテーブルが作成されたかを報告しました。完全に合成された(またはフィルムストリップのような)アニメーションの場合、各フレームに個別のカラーテーブルを持つことは完全に問題なく合理的であり、そのような状況ではこれは問題ではありません。つまり、非常に異なる画像のスライドショーの場合、個別のカラーテーブルを使用すると、最も見栄えの良い結果が得られます。そのため、これは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
" コマンドに割り当てます。
|
![]() |
Giftrans
" を使用して結果のアニメーションを調べると、画像がフレームごとに個別のカラーテーブルではなく、単一の「グローバル」カラーテーブルを使用していることがわかります。![]() ![]() |
画像を一緒に追加する前に「None 」の「-background 」色を使用します。これにより、合成されていないアニメーションでこれを使用でき、不要な色が追加される可能性がありません。特別な " -quantize " 設定の「transparent 」色空間は、IMがカラーマップに半透明色を生成しようとしないようにするために使用されました。半透明を処理できないGIFに結果を保存しているので、無駄なことです。最後に、透明色のためのスペースを残すために、63色に色を減らします。アニメーションによっては透明性が必要なものもあれば、このアニメーションのように、後で圧縮最適化のために透明性が必要になる場合もあります。 |
+map
" も提供しています。これは、上記のDIYメソッドよりもはるかに簡単です。
|
![]() |
![[IM Text]](speed_map_ctables.txt.gif)
![[IM Text]](speed_size.txt.gif)
+map
" 演算子を使用した後、![[IM Text]](speed_map_size.txt.gif)
+map
" 演算子はアニメーションをGIFに保存する前の最後の操作であることが重要です。覚えておいてください
ローカルカラーマップの削除は、GIF形式で保存する前の最後の最適化である必要があります。
順序付きディザ、「静的」の削除


... small number of colors ...小さな動かない領域のフレーム最適化を使用すると、さらに見苦しい静的な長方形領域を取得することさえできます。...順序付きディザ...今のところ、より実用的で詳細の少ないビデオからGIFへの最適化の概要を参照してください。
圧縮の最適化
半透明ピクセルを処理し、色とフレームの最適化を使用してアニメーションをGIF形式で保存すると、GIF圧縮アルゴリズムに対応することで、ファイルサイズをさらに小さくすることができます。GIFファイル形式で使用できるLZW圧縮またはランレングス圧縮は、一定色の大きな領域、または何度も繰り返されるピクセルシーケンスが見つかった場合、よりよく圧縮されます。透明度の最適化
フレームの最適化で見たように、オーバーレイされた画像は、多くの場合、すでに表示されているものを繰り返しているだけです。つまり、GIF廃棄方法が適用された後にすでに存在する同じ色のピクセルをオーバーレイしています。しかし、なぜこれらのピクセルを繰り返す必要があるのでしょうか。すでに画像で透明性を使用している場合は、透明ピクセル色を使用できます。ただし、これらの領域を透明に変換すると、均一な透明ピクセルの領域が大きくなります。これは、オーバーレイされている同じ領域に一致するために必要なさまざまな色を使用するよりも、圧縮率が向上します。たとえば、単純なフレーム最適化、オーバーレイアニメーションを次に示します...
![]() |
![]() |
-layers
」メソッド「OptimizeTransparency
」(IM v6.3.4-4で追加)を使用してみましょう。
|
![]() |
||
![]() |
![[IM Text]](bunny_bgnd_size.txt.gif)
![[IM Text]](bunny_bgnd_opttrans_size.txt.gif)
FUTURE: link to a 'remove background' from animationもちろん、他のほとんどの「
-layers
」メソッド(比較または最適化)と同様に、ファジー係数を指定して、「どの程度類似しているか」色を調整できます。これにより、色のディザリングが不十分なアニメーションを処理できますが、上記の色の最適化を学習していれば、その問題は発生しません。無料のアニメーションGIFツール「InterGIF
」も、上記と同じタイプの透明度圧縮最適化を提供しますが、「ファジー係数」もサポートして「近い」色の変化を透明にする機能はありません。IMが使用できない場合の代替手段としてのみお勧めします。LZW の最適化- (IM以外)
一部のアプリケーションでは、アニメーション内の画像の圧縮率をさらに最適化して、さらに小さくすることができます。ただし、これを行うには、GIF画像形式で一般的に使用されるLZW圧縮に関する専門的な知識が必要です。基本的に、特定のピクセルシーケンスがLZW圧縮アルゴリズムによってすでに処理されている場合、それらを透明ピクセルに変換することはありません。なぜなら、そうすることで画像の圧縮が向上しないからです。奇妙に聞こえますが、 funktioniertです。残念ながら、*ImageMagickはこれを行いません*。これは、一般的なケースで良好な結果を生み出すための適切なヒューリスティックを得るために、非常に多くのスキルとリソースを必要とする複雑なプロセスであるためです。ただし、「-O2
」の最高最適化レベルで「Gifsicle
」アプリケーションを使用して、この手法の実用的な例を示すことができます。
|
![]() |
LZW圧縮最適化により、単純な透明度最適化で画像が![]() ![]() 非可逆 LZW の最適化- (IM以外)別の圧縮改善方法では、ピクセル自体の色をわずかに変更して「近い色のマッチ」にすることで、画像内の色参照の繰り返しを増やします。繰り返されるパターンは当然圧縮率が向上するため、より高い圧縮率を実現できます。以前の「Gifsicle」アプリケーションのフォークであるgiflossyも、「gifsicle 」プログラムを生成しますが、画像をわずかに変更する(「非可逆」)オプションがあり、GIF画像、特にアニメーションのサイズをさらに削減できます。
|