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:基本的な変換(推奨されません)
ffmpeg -i input.mp4 output.gifこれは動作しますが、品質が低いです:FFmpegはビデオの最初の数フレームをサンプリングしてデフォルトパレットを生成し、全ビデオに適用します。色が偏ったビデオでは、他のシーンで色が正しく表現されません。
方法2:二段階アルゴリズム(推奨)
原則
二段階アルゴリズムのコア:
- パレット生成(palettegen):ビデオ全体を分析し、最適な256色パレットを抽出
- パレット使用(paletteuse):生成したパレットで各ピクセルを最適にマッピング
これにより、FFmpegが全シーンを考慮して最適な256色を選択します。
コマンド
# ステップ1:パレットを生成
ffmpeg -i input.mp4 -vf "palettegen" palette.png
# ステップ2:パレットを使用してGIFに変換
ffmpeg -i input.mp4 -i palette.png -filter_complex "paletteuse" output.gifワンステップコマンド
ffmpeg -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gifこれはパレットファイルを生成せず、メモリ内で完了します。
品質最適化テクニック
1. 統計モードの選択
# 全シーンを考慮(デフォルト、より良い品質)
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.pngstats_mode=fullが最も品質が良いですが、最も遅いです。
2. ディザリングアルゴリズム
# 利用可能なディザリングモード
# bayer: 規則的ディザリング、クロスハッチパターン
# heckbert: エラーディフュージョン(デフォルト)
# floyd_steinberg: 最高品質のエラーディフュージョン
# sierra2: Sierra-2-4Aエラーディフュージョン
# none: ディザリングなし、バンディングアーティファクト
ffmpeg -i input.mp4 -i palette.png -filter_complex "paletteuse=dither=floyd_steinberg" output.giffloyd_steinbergが最も自然な結果を生み出しますが、ファイルサイズが大きくなります。
3. 解像度とフレームレートの調整
# 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.gif4. 長さの切り取り
# 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
クロマキー処理
# 緑背景を透明に
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:ブレンド(エッジの混合度合い)
黒背景の透明化
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. 解像度を下げる
# 720p → 480p(ファイルサイズ約50%削減)
ffmpeg -i input.mp4 -vf "scale=480:-1:flags=lanczos" -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif2. フレームレートを下げる
# 30fps → 15fps(ファイルサイズ約50%削減)
ffmpeg -i input.mp4 -vf "fps=15" -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif3. 不要な動きを切り取る
# 最初の5秒のみ
ffmpeg -t 5 -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif4. gifsicleで後処理
# gifsicleで最適化
gifsicle -O3 --lossy=80 -o output.gif input.gif
# 透明度を除去してサイズ削減
gifsicle --no-extensions -o output.gif input.gifgifsicle -O3 --lossy=80は通常、ファイルサイズを30-50%削減し、品質の低下は目立ちません。
実践的なテンプレート
高品質なGIF
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
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
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がパレットを適用。基本テンプレート:
ffmpeg -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif高品質にはstats_mode=fullとdither=floyd_steinbergを追加。ファイルサイズを減らすには解像度とフレームレートを下げる。GIFは短いアニメーションにのみ適しており、長いビデオにはMP4またはWebMを使用してください。
クイックリファレンス:
- 基本コマンド:
ffmpeg -i input.mp4 -filter_complex "[0:v] palettegen [p]; [0:v][p] paletteuse" output.gif - 高品質:
stats_mode=fullとdither=floyd_steinbergを追加 - ファイルサイズ削減: 解像度とフレームレートを下げる
- 後処理:
gifsicle -O3 --lossy=80でさらに30-50%削減