16×16(つまり256パターン)の色をパレットに一時出力し、それを使って色を最適化したファイルが出力する。これにより最適化されたアニメ-ションGIF(アニメGIF、AGIF)や、色の少ないPNG圧縮で効果が期待できる。
16×16 のパレットを作るpalettegen
フィルタと、パレットを元に出力するpaletteuse
フィルタに分けられる。
2023年1月4日のコミットでアルゴリズム周りで大きく改修された。
- A perceptual color space for image processing
- Porting OkLab colorspace to integer arithmetic
- avfilter/palette{gen,use}: add palette utils · FFmpeg/FFmpeg@31c5f26
目次
主な特徴
- 最大256色まで、
透過出力はできない - 透過部分のグラデーションはできない。透過するかしないだけになる
- 色の少ない PNG の色を最適化して圧縮したりアニメGIF向き
- PC画面のスクリーンショットの画像を圧縮するのに重宝できそう
- フルカラーの JPG は意味がない
- 同様に動画にも不向き、グレインが大量に付いて容量が増える
- フルカラーなどの素材にmax_colorsでパレットの色を制限するのは容量の面で効率が良くない(と思う)。この場合にはpixeliz0rフィルタを使って細かいモザイクに加工することでドット絵風にすることができる
- 基本的にはデフォルトの設定で良い
公式ドキュメント
フィルタの解説記事
- リサイズする scale
- trim フィルタの使い方
- Zライブラリを使ったリサイズフィルタ zscale
- ffmpeg で Twitter に投稿できる PNG に変換する
- 輪郭を保護しながらシャープにしたりぼかしたりする unsharp
- 256色のパレットを出力するshowpalette
関連記事
High quality GIF with FFmpeg
How do I convert a video to GIF using ffmpeg, with reasonable quality? – Super User
palettegenのオプション
16×16ピクセルのパレットを作る
ffmpeg -i input -vf palettegen=max_colors=256:reserve_transparent=1:transparency_color=lime:stats_mode=full -update 1 -frames:v 1 palette.png
- max_colors[int]
パレットで使う色の最大値を指定する
既定値:256
範囲:2 から 256 まで - reserve_transparent[boolean]
パレットに透過色を使う。アニメGIFの時に有効化するとうまく最適化される。1枚画像の時には無効にした方がよい
既定値:1(有効) - transparency_color[color]
透過の背景色の指定
既定値:lime - stats_mode[int] 統計モード
- 0, full
全フレームのヒストグラムから計算する。既定値 - 1, diff
前フレームの動いている部分のヒストグラムから計算する - 2, single
毎フレームパレットを作る
- 0, full
metadata
を使って元のフレームに何色使われていて、それがどれくらい減色されたのかを調べることができる。
ffmpeg -i img -vf palettegen,metadata=print:key=lavfi.color_quant_ratio -f null -
singleモードで毎フレームパレットを作る例。
ffmpeg -i input -vf palettegen=stats_mode=single -an -c:v ffv1 palette.mkv
メタデータ出力内容。
lavfi.color_quant_ratio
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:既定値
- 6, sierra3
- 7, burkes
- 8, atkinson
- bayer_scale[int]
ディザーにbayerを使ったときに0から5までの整数が指定できる
0に近いほどグレインは目立つがバンディングは目立たない
5に近いほどグレインは目立たないがバンディングは目立つ
既定値:2
範囲:0 から 5 まで - diff_mode[int]
- 0, none:既定値
- 1, rectangle:映像の一部だけ動いてる場合により最適化される。そうでない場合使わない方が良い
- new[boolean]
複数フレームのパレット入力に対応する。フレーム毎に色が異なるのでその分だけ高画質になるが容量は増える
既定値:0(対応しない) - alpha_threshold[flags]
透過部分の閾値の指定。指定値を超えると不透過になり、下回ると完全な透過になる
既定値:128
範囲:0から255まで - debug_kdtree[string]
Graphvizグラフのkdtreeを指定した場所とファイル名で保存する
既定値:無指定
コマンドサンプル
基本コマンド
静止画像GIF、PNGの場合。PNG出力なら色の少ない画像だとこれも容量削減になる。
ffmpeg -i input -filter_complex palettegen=reserve_transparent=0 tmp.png
ffmpeg -i input -i tmp.png -filter_complex paletteuse output.gif
ffmpeg -i input -i tmp.png -filter_complex paletteuse output.png
実際に使う場合には1行コマンドで実行する方が手軽。
ffmpeg -i input -filter_complex "split[a][b];[a]palettegen[pal];[b][pal]paletteuse" output.png
VLC画面の圧縮比較
動画からアニメGIFを作る
動画からパレットを使ってアニメーションGIFを出力する例。ポイントは-ss、-tを入力オプションで使うところ。適宜フレームレートfps
やリサイズscale
する。以下の例は開始10秒から4秒間で10fpsの横幅320ピクセルでアスペクト比を保持してリサイズしたGIFを出力。
ffmpeg -ss 10 -t 4 -i input -filter_complex "fps=10,scale=320:-2,split[a][b];[a]palettegen[pal];[b][pal]paletteuse" output.gif
容量は大きくなるが、フレーム毎にパレットを使って減色するならpalettegen=stats_mode=2、paletteuse=new=1をつける。
ffmpeg-i input -filter_complex "split[a][b];[a]palettegen=stats_mode=2[pal];[b][pal]paletteuse=new=1" output.gif
動画ファイルを読み込むときに時間が長いほど全てのフレームを調べるのに時間が掛かるので、動画ファイルからパレットを作るときは前もって時間指定してカットしておくか、trim
フィルタを使ってカットする。
ffmpeg -i input -filter_complex trim=start_frame=1536:end_frame=1667,scale=320:-2,palettegen tmp.png
ffmpeg -i input -i tmp.png -filter_complex trim=start_frame=1536:end_frame=1667,scale=320:-2,paletteuse output.gif
1行コマンドなら以下のようになる。
ffmpeg -i input -filter_complex "trim=start_frame=1536:end_frame=1667,scale=320:-2,split[a][b];[a]palettegen[pal];[b][pal]paletteuse" output.gif
ループ回数は-loopを指定する。-1がループしない1回再生。0が無限ループ。1が1度だけループして2回再生。2が2度だけループして3回再生。以下同様。
ffmpeg -ss 10 -t 4 -i input -filter_complex "fps=10,scale=320:-2,split[a][b];[a]palettegen[pal];[b][pal]paletteuse" -loop 0 output.gif
ヘルプコマンド:ffmpeg -h muxer=gif
Gifsicleを使ってさらにGIFを最適化できる。
[…] palettegen / paletteuse – FFmpeg で256色を最適化する | ニコラボ […]