GIF変換時の画質の劣化防止策
はじめに
動画をGIFに変換する方法は色々あるのですが、自分が試した中で画質をなるべく維持できる方法を紹介したいと思います。
事前に断っておきたいのですが、ピクセルアートやフラットデザインのような色数の少ない映像であれば特に調整せずとも画質の劣化が少なくファイル容量も軽くなりますので今回の記事では対象にしておりません。
また、映像の動きが激しいもの、カラフルで色数の多いものは変換する上でどうしても劣化が避けられないものもあり、「全ての映像を劣化なく綺麗にGIF変換できる方法」というものではありませんのでご理解いただけますと助かります。
あと変換にPhotoshopを使いますのでAdobe税を納めてください。
変換方法
先に結果と言いますか、どういう項目を調整すれば良いかだけ紹介します。
後ほど設定の比較画像や、なぜ他の項目を調整しないかなど理由を説明しますがただただ検証の繰り返しなのでお急ぎの方は飛ばしてください。

Photoshopで動画を読み込み、ファイル > 書き出し > Web用に保存 を選択すると変換ウインドウが立ち上がります。
右側の [プリセット] もしくはその下の項目から [ GIF ] を選んで、GIFの変換作業へと移ります。
基本的には以下の項目を調整します。
・減色アルゴリズムを [特定] もしくは[割り付け]切り替えてみて、
見た目の良い方を選んぶ
・ディザアルゴリズムを[パターン]
・透明部分にチェック
・カラーはなるべく多く。あまりにも重すぎる場合は数値を減らす
・webスナップ、劣化は使用しない
Photoshopでの変換で画質を維持するならこの方法が良いと思いますが、GIF変換する目的はTwitterへの投稿やその他SNSサイトでの掲載がメインだと思いますので容量制限がかかってしまい、その容量を超えてしまうことがよくあると思います。(変換画面では下の方に変換後の容量が表記されます)
さらに圧縮する方法
GIFのファイル容量を削りたい場合は、以下のサイトをお勧めします
https://ezgif.com/optimize
ezgif.comはさまざまなフォーマットをGIFに変換してくれるサービスでもあるのですが、GIF圧縮を最適化してくれる機能もあります。
(最適化と言っても原理はよくわからず、低容量を目指すと画質は劣化します。)
一度変換したGIFを上記リンクでアップロードし、
Optimization method で Lossy GIF を選び、
Compression level を 5〜200の間で調整します。

Compression level の数値が大きいほど圧縮率が高くなり軽量になるのですが、数値と圧縮率は比例しているわけではなくかなりまばらです。
Compression level が5〜30で容量が全然減らなくても31を選んだ途端に急に軽くなったりします。
また変換する映像の色や動きによって圧縮度合いが異なりますので、
Compression level が5でも元データよりかなり軽くなったり、逆に全く容量に変化がない場合もありますので、いくつか数値を変えて試してみて、目標にしている容量に近づけてみてください。
それでも容量が厳しい場合
ここまでしても容量や画質に納得できない場合は
・解像度を下げる
・フレーム数を少なくする(尺を削るか、フレームレートを下げる
・色を減らす(メインのカラーに4色使ってるなら3色、2色に減らすなど
GIFはmp4などの動画フォーマットと比べ重くなりがちで、圧縮にも限度があります。どうしても容量や画質が許容できない場合は GIF を使うことを諦めるか、動画の内容を改める方が良いかもしれません。
細かな説明
ここからは冒頭でも書いていたように、機能の比較や説明していない項目などに触れていきたいと思います。
まずPhotoshopのGIF変換の各項目の名称です。
各項目にマウスオーバーしないとどういう機能か表示されないので見やすいようにまとめました。

減色アルゴリズム
GIFは色を256色(RGBそれぞれではなく、RGBまとめて)しか保持できないので、指定したアルゴリズムによって元データの色を256色(もしくは⑤で指定した色数)まで減らします。ディザアルゴリズムの指定
減色しただけでは色の階調が目立つ(特にグラデーションにマッハバンドのような段差ができる)ので、それを馴染ませるためにディザリング(拡散)します。カラーの不透明度に基づいた透明部分を含める
GIFに透過情報を含めるか否かです。チェックを入れることで256色のうち1色を透過ピクセルとして使ってしまうのですが、ほぼ見た目が変わらず容量が少し減らせるので基本ONにしておきます。透明ディザアルゴリズムの指定
透明度部分のディザアルゴリズムを決めます。今回は透過GIFを想定していないので無視します。カラーテーブルで使用できるカラーの最大数
先ほど触れていた256色の制限からさらに色数を減らすことができます。
減らすほど画質は落ちるのですが、ファイル容量を削減できます。ディザの適用量
特定のアルゴリズムを選ぶと拡散度合いを調整できます。透明ピクセルを合成させるカラーを定義
透過GIFをwebページに載せる際の背景色との馴染ませ、だと思います。
透過GIF作らないので正直この項目は分かっていません…透明ディザの適用量
特定のアルゴリズムを選ぶと拡散度合いを調整できます。許容量に基づいて近似値をWebパレットにスナップ
その昔、webページで再現できる色がOSや機種によって異なっていたのでどれでも対応できるよう制限された色、に抑える機能です。令和なので無視してください。非可逆圧縮の許容値を指定
画面に書かれている通り劣化しますので無視してください。
ざっと項目の説明をしましたが、あからさまに画質を下げる項目(色数、webスナップ)は常に最良値にしておいて、それらを除けば
減色アルゴリズム と ディザアルゴリズム の2点を正しく見極められれば画質の劣化が抑えられると思います。
では実際に比較して、どの設定が良い結果を出せるか評価してみましょう。
減色アルゴリズムの比較

減色アルゴリズムはプリセットで9種(プリセットから色数などをいじるとカスタムに切り替わるので実質8種)選ぶことができます。
画質を見極めるときは変換画面の上部から2アップを選び、変換前の元データとGIF変換後の2画面を表示させると画質の変化がわかりやすいです。
今回は400%まで拡大しピクセルがよくわかる状態で比較します。
このwebサイトでは画像をクリックして左右(クリックかキーボード)に送って切り替えるか、右クリックして新しいタブでそれぞれ開いて比較してみてください。難しい場合は以下のリンクでデータを共有しております。
https://www.dropbox.com/sh/ayc90hsaimyuch6/AABWum0hwv2YdwucCCbpPMj_a?dl=0
背景の黒の僅かなグラデーションやガラスの陰影部分を見比べると変化がわかりやすいと思います。

[ 知覚的 ]は後述する[ 特定 ][ 割り付け ]と並んで画質が劣化しにくいアルゴリズムです。
ただ、これは僕の感覚ではあるのですが、[ 特定 ]や[ 割り付け ]と見比べても同じ結果を出すことが多く、まれにそれらより画質が悪くなることがあります。知覚的で他のアルゴリズムより良い結果を得られることがほぼないので最初に紹介した方法では省いておりました。

[ 特定 ]は比較的全体がなだらかになることが多い印象です。ただ一部、彩度が強くピクセル数が少ない箇所は色が省かれたりするのでカラフルな映像だと注意が必要です。

[ 割り付け ]はなるべく使われている色を残そうとする印象が強く、[ 特定 ]のように色を切り捨てるようなことが起きにくいです。ただ、ディザアルゴリズムの影響を受けやすく、僅かな陰影にもピクセルが拡散してしまうようなところがあり、むしろ黒潰れや白潰れのようにフラットに出したい時に不便です(記事の最後の方で細かく比較します)

[ 制限(web)]はWebセーフカラーに対応させた色のみに減色されます。
合わせて色数も減らされるのでメリットがなく使いません。

[ モノクロ2階調 ]、名前の通りですね。白と黒の2色のみで構成されます。色を使いたいので不要です。

[ グレースケール ]。見た目通りです。色を使いたいので不要です。

[ Mac OS ]Mac向けのカラーに絞っているようですが、いつの時代のMacを指しているか不明です。こちらも使いません。

[ Windows ]こちらも上記同様、現代では不必要な制限がかかるため使いません。
以上が減色アルゴリズムの比較になりますが、[ 特定 ]と[ 割り付け ](+αで知覚的)が比較的劣化しにくいと思います。
ディザアルゴリズムの比較

続いてディザリングも見比べてみます。(減色アルゴリズムとの組み合わせも影響しますが、全て試すと非常に多くなってしまうので[ 特定 ]だけで行います)

[ ディザなし ]では拡散が全くなく滑らかな階調を出すことが難しいです。
ピクセルアートやシンプルなグラフィックであれば有用かもしれませんが、今回は想定していないので検討から除外します。


[ 誤差拡散法 ]は右のディザの値を増やさないとディザなしと同等となります。ディザの値を増やすことで拡散していきます。ただ、今回で言えば背景上部の円形のグラデーションが拡散はしているもののまだ不自然な諧調が残っているように見えます。

[ パターン ]は等間隔にならぶピクセルが目立つのですが、個人的にはこれが一番馴染んで見えるように感じます。色数が少ないため諧調を表現するのが難しいのですが、濃い色と薄い色を交互に並べることで階調を出しています。このような薄いグラデーションが広がっている映像だと目立つのですが、密度の高い映像ではあまり目立たないです。

[ ノイズ ]は[ 誤差拡散法 ]をさらにノイズを加えて拡散させたような感じです。静止画で見ると許容できそうな範囲かもしれませんが、アニメーションさせるとノイズが暴れて目立ってしまうのであまり見栄えがよくありません。
以上がディザアルゴリズムの比較です。[ パターン ]のピクセルが並んでいる感じが許容できなければ、[ ノイズ ]か[ 誤差拡散法 ]を選ぶことになると思います。個人的には[ パターン ]が一番マシに見えます。
こうやって比較していくと調整できる項目が限られているのがわかるかなと思います。もう少しだけ劣化を抑えるために再度減色アルゴリズムの比較を行います。
減色の[ 特定 ][ 割り付け ]の比較
減色アルゴリズムで劣化の少なかった二つを改めて比較してみます。
丸で囲った部分が違いが顕著に出ています。


パッとみた感じでは[ 割り付け ]の方が綺麗に感じます。
真ん中の丸では青い筋にもちゃんと色が乗っていて、左の丸い部分ではノイズも少ないです。
ただ、右下の黒い部分では[ 特定 ]だと綺麗に単色になっているのに対し、[ 割り付け ]ではディザリングされた[ パターン ]の模様が浮かびあがっています。
力技として、模様が浮かび上がっているピクセルの色をカラーテーブルから削除して馴染ませる方法もあるのですが、調整が大変なことと他の色の分布に影響してさらに劣化してしまうことがあるので諦めた方が時間を有効活用できると思います。
どちらを優先して選ぶかは好みではあるのですが、こう言った違いが作る映像によって[ 特定 ]の方が目立ちにくかったり、逆に[ 割り付け ]の方が綺麗に出たりするので、変換の都度、比較してみることをおすすめします。
と言った感じで冒頭の変換方法に繋がる感じです。
Photoshop以外にもGIF変換してくれるツールやプラグインはあるのですがPhotoshopのように細かくチューニングできるものがないので、面倒で時間がかかりますがこの方法でやっています。
GIF変換に時間がかかったり途中で中断できないなど不便ではありますが、この記事に目を通して頂いて、画質の改善と試行錯誤の手間が減ると嬉しいです。
無劣化軽量爆速ツールがあれば是非紹介してください。