ffmpeg で 256色を最適化する


master で palettegenpaletteuse フィルタが追加された。16×16(つまり256パターン)のパレットに色を一時出力し、それを使い最適化されたファイルが出力できるようになった。これにより最適化されたアニメGIFや、色の少ないPNG圧縮で効果が期待できる。

16×16 のパレットを作る palettegen と、palettegen で作られたパレットを元に出力する paletteuse に分けられる。

主な特徴

  • 最大256色まで、透過出力はできない
  • 色の少ない PNG の色を最適化して圧縮したりアニメGIF向き
  • PC画面のスクリーンショットの画像を圧縮するのに重宝できそう
  • フルカラーの JPG は意味がない
  • 同様に動画にも不向き、グレインが大量に付いて容量が増える
  • フルカラーなどの素材に max_colors でパレットの色を制限するのは容量の面で効率が良くない(と思う)
  • 基本的にはデフォルトの設定で良い

palettegen のオプション

ffmpeg -i input -vf palettegen=max_colors=256:reserve_transparent=1:stats_mode=full palette.png

  • max_colors[int]
    パレットで使う色の最大値を指定する
    既定値:256
    範囲:4 から 256 まで
  • reserve_transparent[boolean]
    パレットに透過色を使う。GIFアニメの時に有効化するとうまく最適化される
    既定値:1(有効)
  • stats_mode[int]
    統計モード
    • 0, full
      全フレームのヒストグラムから計算する。既定値
    • 1, diff
      前フレームのヒストグラムから計算する
      映像全体が動く場合はこちらの方が容量が小さくなりがち
    • 2, single
      毎フレームパレットを作る

metadata を使って元のフレームに何色使われていて、それがどれくらい減色されたのかを調べることができる
ffmpeg -f lavfi -i movie=img,palettegen,metadata=print:key=lavfi.color_quant_ratio -f null -
single モードで毎フレームパレットを作る例
ffmpeg -i input -vf palettegen=stats_mode=single -an -vcodec ffv1 palette.mkv

paletteuse のオプション

ffmpeg -i input -i palette.png -filter_complex paletteuse=dither=bayer:bayer_scale=2 output.gif
複数フレームのパレットを読み込む例
ffmpeg -i input -i palette.mkv -filter_complex paletteuse=new=1 output.gif

  • dither[int]
    設定できるディザーのアルゴリズムは以下
    • 0, none:容量は一番小さくなるがバンディングが目立つ
    • 1, bayer
    • 2, heckbert
    • 3, floyd_steinberg
    • 4, sierra2
    • 5, sierra2_4a:既定値
  • bayer_scale[int]
    ディザーに bayer を使ったときに 0 から 5 までの整数が指定できる
    0 に近いほどグレインは目立つがバンディングは目立たない
    5 に近いほどグレインは目立たないがバンディングは目立つ
    既定値:2
    範囲:0 から 5 まで
  • diff_mode[int]
    • 0, none:既定値
    • 1, rectangle:映像の一部だけ動いてる場合により最適化される。そうでない場合使わない方が良い
  • new[boolean]
    複数フレームのパレット入力に対応する。フレーム毎に色が異なるのでその分高画質になるが容量は増える
    既定値:0(未対応)

コマンドサンプル

基本コマンド

paletteuse で gif 出力ならきれいな gif に。
png 出力なら色の少ない画像だとこれも容量削減になる。
ffmpeg -i input -filter_complex palettegen tmp.png
ffmpeg -i input -i tmp.png -filter_complex paletteuse output.gif
ffmpeg -i input -i tmp.png -filter_complex paletteuse output.png

lightscreen で VLC のスクリーンショットを撮った画像の圧縮比較

オリジナル画像(PNG):27.9 KB


この方法で圧縮した画像(PNG):17.7 KB(約37%減)

動画からリサイズしフレーム数を指定してアニメGIFを作る

動画ファイルを読み込むときに時間が長いほど全てのフレームを調べるのに時間が掛かるので、動画ファイルからパレットを作るときは前もって時間指定してカットしておくか、trim フィルタを使ってカットする。
ffmpeg -i input -filter_complex scale=320:-1,trim=start_frame=1536:end_frame=1667,palettegen tmp.png
ffmpeg -i input -i tmp.png -filter_complex scale=320:-1,trim=start_frame=1536:end_frame=1667,paletteuse output.gif

SHIROBAKO の2期のOPの1シーン

Gifsicle を使ってさらに GIF を最適化できる。
[FFmpeg] FFgif: a batch script helper for transcoding videos to GIF | 舶来ゴミ置き場

unsharp フィルタを使う

映像をくっきりさせることもできるが少し容量が増える

ffmpeg -i input -i tmp.png -filter_complex scale=320:-1,unsharp=3:3:0.5,trim=start_frame=1536:end_frame=1667,paletteuse output.gif

バッチファイル配布

2つのバッチファイルともに「入力ファイル_tmp.png」を一時出力して削除している。出力した画像は入力した画像と同じ場所に保存される。

D&D の複数ファイル読み込みに対応の PNG 最適バッチファイル
複数ファイルは未対応のアニメGIF作成バッチファイル 引数にファイル名と開始フレームと終了フレームを指定する Gifsicle for Windows も併用する。
-f gif で標準出力するので gifsicle で最適化される前のファイルは出力されない。ffmpeg と gifsicle の 32bit か 64bit で揃える。
gif_anime.bat input.mp4 100 200

公式ドキュメント

フィルタの解説記事

trim フィルタの使い方

関連記事

High quality GIF with FFmpeg
[AviUtl] Direct Animated GIF Export Plugin | 舶来ゴミ置き場
一番手早いの方法でビディオから動画GIFに変換 – Yahoo!知恵袋

コメントを残す

メールアドレスが公開されることはありません。