Skip to content

MP4からGIF変換チュートリアル:FFmpeg二段階アルゴリズムと品質最適化

MP4をGIFに変換するのは簡単ですが、良い品質のGIFを作るのは難しいです。多くの人がffmpeg -i input.mp4 output.gifを実行して、ブロックノイズだらけのGIFを取得します。問題はGIFが256色しかサポートしていないことです。このチュートリアルでは、FFmpegのpalettegen/paletteuse二段階アルゴリズムを解説し、GIFの原則から最適化までをカバーします。

なぜGIF変換が難しいのか

GIFフォーマットの制限:

  • 256色のみ:MP4の数百万色に対して、GIFは256色しか保存できません
  • 非圧縮:H.264のようなフレーム間圧縮がなく、ファイルが巨大
  • 音声なし:アニメーション画像のみ
  • 1ビット透明度:半透明なし、完全に透明または完全に不透明のみ

重要な課題: MP4の数百万色を256色に削減する方法。これがカラークオンタイゼーション(Color Quantization)と呼ばれ、GIF品質を決定する鍵です。

方法1:基本的な変換(推奨されません)

bash
ffmpeg -i input.mp4 output.gif

これは動作しますが、品質が低いです:FFmpegはビデオの最初の数フレームをサンプリングしてデフォルトパレットを生成し、全ビデオに適用します。色が偏ったビデオでは、他のシーンで色が正しく表現されません。

方法2:二段階アルゴリズム(推奨)

原則

二段階アルゴリズムのコア:

  1. パレット生成(palettegen):ビデオ全体を分析し、最適な256色パレットを抽出
  2. パレット使用(paletteuse):生成したパレットで各ピクセルを最適にマッピング

これにより、FFmpegが全シーンを考慮して最適な256色を選択します。

コマンド

bash
# ステップ1:パレットを生成
ffmpeg -i input.mp4 -vf "palettegen" palette.png

# ステップ2:パレットを使用してGIFに変換
ffmpeg -i input.mp4 -i palette.png -filter_complex "paletteuse" output.gif

ワンステップコマンド

bash
ffmpeg -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

これはパレットファイルを生成せず、メモリ内で完了します。

品質最適化テクニック

1. 統計モードの選択

bash
# 全シーンを考慮(デフォルト、より良い品質)
ffmpeg -i input.mp4 -vf "palettegen=stats_mode=full" palette.png

# 各フレームの差分のみ考慮(速い、小さなパレット)
ffmpeg -i input.mp4 -vf "palettegen=stats_mode=diff" palette.png

# 単一フレーム(速い、品質最低)
ffmpeg -i input.mp4 -vf "palettegen=stats_mode=single" palette.png

stats_mode=fullが最も品質が良いですが、最も遅いです。

2. ディザリングアルゴリズム

bash
# 利用可能なディザリングモード
# bayer: 規則的ディザリング、クロスハッチパターン
# heckbert: エラーディフュージョン(デフォルト)
# floyd_steinberg: 最高品質のエラーディフュージョン
# sierra2: Sierra-2-4Aエラーディフュージョン
# none: ディザリングなし、バンディングアーティファクト

ffmpeg -i input.mp4 -i palette.png -filter_complex "paletteuse=dither=floyd_steinberg" output.gif

floyd_steinbergが最も自然な結果を生み出しますが、ファイルサイズが大きくなります。

3. 解像度とフレームレートの調整

bash
# 480p、15fps(サイズ削減)
ffmpeg -i input.mp4 -vf "scale=480:-1:flags=lanczos,fps=15" -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

# 640p、10fps(さらに小さく)
ffmpeg -i input.mp4 -vf "scale=640:-1:flags=lanczos,fps=10" -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

4. 長さの切り取り

bash
# 5秒間のクリップのみ
ffmpeg -t 5 -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

# 10秒から5秒間
ffmpeg -ss 10 -t 5 -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

透明背景のGIF

クロマキー処理

bash
# 緑背景を透明に
ffmpeg -i input.mp4 -filter_complex "[0:v] colorkey=0x00FF00:0.3:0.2 [greenless]; [greenless] palettegen=reserve_transparent=1 [p]; [greenless][p] paletteuse=alpha_threshold=128" output.gif

パラメータ:

  • 0x00FF00:緑色キー
  • 0.3:類似度(0.3 = 30%の色差を許容)
  • 0.2:ブレンド(エッジの混合度合い)

黒背景の透明化

bash
ffmpeg -i input.mp4 -filter_complex "[0:v] colorkey=0x000000:0.1:0.0 [bgless]; [bgless] palettegen=reserve_transparent=1 [p]; [bgless][p] paletteuse=alpha_threshold=128" output.gif

ファイルサイズ最適化

1. 解像度を下げる

bash
# 720p → 480p(ファイルサイズ約50%削減)
ffmpeg -i input.mp4 -vf "scale=480:-1:flags=lanczos" -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

2. フレームレートを下げる

bash
# 30fps → 15fps(ファイルサイズ約50%削減)
ffmpeg -i input.mp4 -vf "fps=15" -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

3. 不要な動きを切り取る

bash
# 最初の5秒のみ
ffmpeg -t 5 -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

4. gifsicleで後処理

bash
# gifsicleで最適化
gifsicle -O3 --lossy=80 -o output.gif input.gif

# 透明度を除去してサイズ削減
gifsicle --no-extensions -o output.gif input.gif

gifsicle -O3 --lossy=80は通常、ファイルサイズを30-50%削減し、品質の低下は目立ちません。

実践的なテンプレート

高品質なGIF

bash
ffmpeg -i input.mp4 \
  -vf "scale=720:-1:flags=lanczos,fps=24" \
  -filter_complex "[0:v] palettegen=stats_mode=full [p]; [0:v][p] paletteuse=dither=floyd_steinberg" \
  output.gif

ウェブ用GIF

bash
ffmpeg -i input.mp4 \
  -vf "scale=480:-1:flags=lanczos,fps=15" \
  -filter_complex "[0:v] palettegen=stats_mode=full [p]; [0:v][p] paletteuse=dither=floyd_steinberg" \
  output.gif

小さなGIF

bash
ffmpeg -t 5 -i input.mp4 \
  -vf "scale=320:-1:flags=lanczos,fps=10" \
  -filter_complex "[0:v] palettegen=stats_mode=full [p]; [0:v][p] paletteuse=dither=sierra2" \
  output.gif

# gifsicleでさらに最適化
gifsicle -O3 --lossy=80 -o output-final.gif output.gif

よくある問題

問題原因解決策
GIFがブロックノイズだらけデフォルトパレット使用二段階アルゴリズム使用
GIFが巨大非圧縮フォーマット解像度とフレームレートを下げる
色が不正確パレットが適切でないstats_mode=full使用
バンディングディザリング不足dither=floyd_steinberg使用
GIFが途切れるフレームレート低すぎfps=15以上使用
透明背景にアーティファクト1ビット透明度alpha_threshold調整
変換が遅いstats_mode=fullが遅いstats_mode=diff使用

まとめ

GIF変換のコアは二段階アルゴリズム:palettegenがパレットを生成、paletteuseがパレットを適用。基本テンプレート:

bash
ffmpeg -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif

高品質にはstats_mode=fulldither=floyd_steinbergを追加。ファイルサイズを減らすには解像度とフレームレートを下げる。GIFは短いアニメーションにのみ適しており、長いビデオにはMP4またはWebMを使用してください。

クイックリファレンス:

  • 基本コマンド: ffmpeg -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif
  • 高品質: stats_mode=fulldither=floyd_steinbergを追加
  • ファイルサイズ削減: 解像度とフレームレートを下げる
  • 後処理: gifsicle -O3 --lossy=80でさらに30-50%削減

参考文献

最終更新: