標準で使えるscaleフィルタの使い方。外部ライブラリにzscaleフィルタがありこちらはHDR、高品質リサイズ向けで処理速度はscaleフィルタより速くない2022年3月4日のコミットで同程度に速くなった。

基本コマンド

アスペクト比を維持しながら横幅1280ピクセルにリサイズする。
ffmpeg -i input -vf scale=1280:-1 output

さらに縦幅が奇数になる場合には繰り上げて偶数にする。
ffmpeg -i input -vf scale=1280:-2 output

アスペクト比を維持しながら長辺1280ピクセルより大きいとき長辺1280ピクセルにリサイズする。小さければそのまま。
ffmpeg -i input -vf "scale=if(gte(iw\,ih)\,min(1280\,iw)\,-2):if(lt(iw\,ih)\,min(1280\,ih)\,-2)" output

アスペクト比を維持して最大横幅が1280ピクセル、縦幅が720ピクセルまで。
ffmpeg -i input -vf "scale=1280x720:force_original_aspect_ratio=decrease" output

リサイズ方法をlanczosに変える。
ffmpeg -i input -vf scale=1280:-2:flags=lanczos output
ffmpeg -i input -vf scale=1280:-2 -sws_flags lanczos output

lanczosaccurate_rndを併用する。
ffmpeg -i input -vf scale=1280:-2 -sws_flags lanczos+accurate_rnd output

ガンマ補正を行う。既定値では行わない。
ffmpeg -i input -vf scale=1280:-2 -gamma 1 output

横幅が1280ピクセル未満はリサイズせずに、超えたら横幅1280ピクセルをアスペクト比に合わせて縦幅をリサイズする。
ffmpeg -i input -vf scale=min(1280\,iw):min(-2\,ih) output

解像度1920×1080以下はリサイズせずに、超えた分のアスペクト比の大きい方に合わせて1920×1080に収まるようにリサイズする。
ffmpeg -i input -vf scale=iw*min(1920/iw\,1080/ih):ih*min(1920/iw\,1080/ih) output

sardarが通常のではなく、出力時に指定したdarと縦幅でリサイズする。例は16:9で縦幅720ピクセルに横幅を自動に合わせる。16:9なので横幅は1280ピクセルになる。
ffmpeg -i input -vf setsar=1,setdar=dar=16/9,scale=(dar*oh):720 output

evalの利用例。出力解像度は変更できないので複数の映像を合わせる。例えばoverlayフィルタなどで使える。
ffmpeg -i input1 -i input2 -filter_complex [1:v]scale=-1:ih-100*t:eval=frame[top];[0:v][top]overlay=x=100:y=100:shortest=1 output

映像の上に映像をのせる overlay

上の例だとoverlayフィルタの指定座標に向かってリサイズする。2入力目の映像の中心に向かってリサイズするにはoverlayフィルタの座標も動的に変更する。これを一度に行うのがzoompanフィルタだがまだ記事を書いていない。
ffmpeg -i input1 -i input2 -filter_complex [1:v]scale=-1:ih-100*t:eval=frame[top];[0:v][top]overlay=x=100+100*t:y=100+100*t:shortest=1 output

video – ffmpeg: How to scale .png over time – Super User
animation – ffmpeg scale down video dynamically (squeeze-back) or zoompan out to smaller than original – Stack Overflow

yuvjのついたフルレンジピクセルフォーマットにHEVCは対応しているが、AVC、jpeg2000、AV1等は対応してないので出力カラーレンジにリミテッドレンジをつける。AVCのx264(libx264)は対応している、
ffmpeg -i yuvj_input -vf scale=out_range=tv -c:a copy output

他の方法
色の情報の扱いについて | フルレンジからの変換

BGR(RGBではない)からYUVに変換するときはscaleフィルタのフラグにaccurate_rndをつける。
ffmpeg -i bgr_input -vf scale=flags=accurate_rnd -c:a copy output

インターレース保持しながらリサイズ。
ffmpeg -i input.ts -vf scale=-2:720:interl=1 -c:v libx264 -flags +global_header+ilme+ildct -weightp 0 -c:a aac output.mp4

ffmpegのwiki:Scaling – FFmpeg
公式ドキュメント:FFmpeg Filters Documentation : scale

オプション

  • width, w[string]
    出力解像度の横幅。0は入力と同じ。-1はアスペクト比を揃えて縦解像度に合わせる。-nでnの倍数で割りきれるように繰り上げて調整する
  • height, h[string]
    出力解像度の縦幅。0は入力と同じ。-1はアスペクト比を揃えて横解像度に合わせる。-nでnの倍数で割りきれるように繰り上げて調整する
  • size, s[string]
    横幅x縦幅。使える書式
  • flags[string]
    リサイズアルゴリズムの指定。+をつけて複数指定できる。設定値は後述
  • interl[boolean]
    インターレース保持指定。実際に保持できるかどうかはエンコーダ次第。libx264は保持できるが別途パラメータが必要。ほかにもmpeg2videoh264_nvencTuring以前)などがある。
    • 0:保持しない。既定値
    • 1:保持する
  • in_color_matrix[string]
    入力カラーマトリクス
    • auto:既定値
    • bt601
    • bt470
    • smpte170m
    • bt709
    • fcc
    • smpte240m
    • bt2020
  • out_color_matrix[string]
    出力カラーマトリクス
    設定値はin_color_matrixと同じ
  • in_range[int]
    入力カラーレンジ
    • 0, auto, unknown:既定値
    • 1, mpeg, limited, tv
    • 2, jpeg, full, pc
  • out_range[int]
    出力カラーレンジ。設定値はin_rangeと同じ
  • in_v_chr_pos[int]
    縦方向の入力クロマポジション
    既定値:-513(無指定扱い)
    範囲:-513から512まで
  • in_h_chr_pos[int]
    横方向の入力クロマポジション
    既定値:-513(無指定扱い)
    範囲:-513から512まで
  • out_v_chr_pos[int]
    縦方向の出力クロマポジション。out_h_chr_pos=0:out_v_chr_pos=128chroma_sample_loc_type=0のleft。out_h_chr_pos=0:out_v_chr_pos=0chroma_sample_loc_type=2のtop leftになる
    既定値:-513(無指定扱い)
    範囲:-513から512まで
  • out_h_chr_pos[int]
    横方向の出力クロマポジション
    既定値:-513(無指定扱い)
    範囲:-513から512まで
  • force_original_aspect_ratio[int]
    scaleフィルタの縦横(w, h)どちらに合わせアスペクト比(DAR)維持してリサイズするか
    • 0, disable:無効。既定値
    • 1, decrease:短い方に合わせる
    • 2, increase:長い方に合わせる
  • force_divisible_by[int]
    force_original_aspect_ratioと併用することでforce_divisible_byの値に最も近い許容倍数に丸める
    既定値:1
    範囲:1から256まで
  • param0, param1[double]
    lanczosで使うreddit
    bicubicでも使える。redditWikipedia
  • nb_slices[int]
    スライス数の指定。デバグ目的で利用。削除された
    既定値:0
  • eval[int]
    リサイズの評価方法
    • 0, init:1フレーム目で固定。既定値
    • 1, frame:フレーム毎に変動

縦横幅に使える書式

これも使える。ffmpeg で使える評価式

  • in_w, iw:入力横幅
  • in_h, ih:入力縦幅
  • out_w, ow:横幅(width, w)で指定した値。縦幅の指定に横幅でリサイズした後の値を使うときに使う
  • out_h, oh:縦幅(height, h)で指定した値。横幅の指定に縦幅でリサイズした後の値を使うときに使う
  • a:iw / ih
  • sar:サンプルアスペクト比
  • dar:(iw / ih) * sar
  • hsub, vsub:入力クロマサブサンプル値。yuv422pだと hsubは2、vsubは1
  • ohsub, ovsub:出力クロマサブサンプル値。yuv422pだと hsubは2、vsubは1

evalに使える書式

  • n
    0から始まるフレーム番号
  • t
    タイムスタンプ秒
  • pos
    デコード時点での合計ファイルサイズ

リサイズアルゴリズム

-sws_flagsからアルゴリズムを指定できる。-sでのリサイズと、-vfのscaleフィルタでflagsを指定しないとbicubicが使われるが、-filter_complexのscaleフィルタでflagsを指定しないとbilinearが使われてアルゴリズムが異なる。この仕様は2021年8月5日のコミット、バージョンでは4.4以降で直り、無指定でbicubicが使われるようになった。

  • fast_bilinear
  • bilinear
  • bicubic
  • experimental
  • neighbor
  • area
  • bicublin
  • gauss
  • sinc
  • lanczos
  • spline
  • print_info
  • accurate_rnd
  • full_chroma_int
  • full_chroma_inp
  • bitexact
  • error_diffusion

公式ドキュメント:FFmpeg Scaler Documentation : sws_flags

ディザーアルゴリズム

-sws_ditherからアルゴリズムを指定できる。

  • 0, none
  • 1, auto:swsから児童に選ばれる。既定値
  • 2, bayer
  • 3, ed:error diffusion
  • 4, a_dither:arithmetic addition dither
  • 5, x_dither:arithmetic xor dither

公式ドキュメント:FFmpeg Scaler Documentation : sws_dither

5 thoughts on “リサイズする scale

  • KSK

    > yuvjのついたフルレンジピクセルフォーマットにHEVCは対応しているが、AVC、jpeg2000、AV1等は対応してない

    これは知りませんでした。H.264に変換しようとしていましたが、H.265にします。

    • admin

      いつからこの記述になっているか記憶があいまいですが、AVCは未対応ではなく、x264(libx264)は対応しています。なので訂正しました。

      ffmpeg -h encoder=libx264 | grep pixel
      Supported pixel formats: yuv420p yuvj420p yuv422p yuvj422p yuv444p yuvj444p nv12 nv16 nv21 yuv420p10le yuv422p10le yuv444p10le nv20le gray gray10le

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)