Changes between Version 27 and Version 28 of Scaling


Ignore:
Timestamp:
May 3, 2024, 3:20:48 AM (2 years ago)
Author:
MasterQuestionable
Comment:

Hint. Minor.

Legend:

Unmodified
Added
Removed
Modified
  • Scaling

    v27 v28  
    1 FFmpeg has got a very powerful [https://ffmpeg.org/ffmpeg-filters.html#scale scale filter], which can be used to accomplish various tasks. Some of them are listed here.  More can be found in the [https://ffmpeg.org/ffmpeg-filters.html#scale official documentation]. 
     1FFmpeg has got a very powerful [https://ffmpeg.org/ffmpeg-filters.html#scale scale filter], which can be used to accomplish various tasks. Some of them are listed here. More can be found in the [https://ffmpeg.org/ffmpeg-filters.html#scale official documentation].
    22
    3 {{{
    4 #!div style="border: 1px solid #e5c7c7; margin: 1em; background-color: #fdd;"
     3{{{#!div style="margin-left: 1em; border: 1px solid #e5c7c7; background-color: #FDD"
    54'''Warning:'''
     5* https://trac.ffmpeg.org/ticket/10993
    66* When using `-filter_complex`/`-lavfi`, the default scaling flags are not applied, so the default algorithm is not `bicubic`, but `bilinear`. To achieve the same results for complex filter chains, you have to explicitly set the scaling algorithm via the `flags=bicubic` option. That was fixed in 9f14396a5103ec80893db801035ece5d14c0d3c5.
    77* In some cases, FFmpeg will set the Sample Aspect Ratio to compensate for the ratio change. You have to manually set the SAR value to 1:1 to make the players display it in the way you want. For example:
     
    1717* Dither can be turned off using -vf scale=sws_dither=none
    1818* One should always remember that YCbCr 4:4:4 8 bit is not enough to preserve RGB 8 bit, YCbCr 4:4:4 10 bit is required.
    19 * The default for matrix in untagged input and output is always limited  BT.601
     19* The default for matrix in untagged input and output is always limited BT.601
    2020}}}
    2121
    2222In all the examples, the starting image (input.jpg) will be this one (535×346 pixels):
     23[[Image(input.jpg)]]
    2324
    24 [[Image(input.jpg)]]
    2525
    2626== Simple Rescaling ==
     
    3535}}}
    3636The resulting image will look like this:
    37 
    3837[[Image(output_320x240.png)]]
    3938
    4039As you can see, the aspect ratio is not the same as in the original image, so the image appears stretched.
    4140
     41
    4242== Keeping the Aspect Ratio ==
    4343
    4444If we'd like to keep the aspect ratio, we need to specify only one component, either width or height, and set the other component to -1. For example, this command line:
    45 
    4645{{{
    4746ffmpeg -i input.jpg -vf scale=320:-1 output_320.png
    4847}}}
     48will set the width of the output image to 320 pixels and will calculate the height of the output image according to the aspect ratio of the input image.
    4949
    50 will set the width of the output image to 320 pixels and will calculate the height of the output image according to the aspect ratio of the input image. The resulting image will have a dimension of 320×207 pixels.
    51 
     50The resulting image will have a dimension of 320×207 pixels.
    5251[[Image(output_320.png)]]
    5352
    5453Some codecs require the size of width and height to be a multiple of ''n''. You can achieve this by setting the width or height to ''-n'':
    55 
    5654{{{
    5755ffmpeg -i input.jpg -vf scale=320:-2 output_320.png
    5856}}}
     57The output will now be 320×206 pixels.
    5958
    60 The output will now be 320×206 pixels.
    6159
    6260== Using Variables ==
     
    6563
    6664For example, if you want to stretch the image in such a way to only double the width of the input image, you can use something like this (`iw` = input width, `ih` = input height):
    67 
    6865{{{
    6966ffmpeg -i input.jpg -vf "scale=iw*2:ih" input_double_width.png
     
    7168
    7269The output image will look like this:
    73 
    7470[[Image(input_double_width.png)]]
    7571
    7672If you want to half the size of the picture, just multiply by .5 or divide by 2:
    77 
    7873{{{
    7974ffmpeg -i input.jpg -vf "scale=iw*.5:ih*.5" input_half_size.png
     
    8681}}}
    8782
     83
    8884== Avoiding Upscaling ==
    8985
    9086Sometimes you want to scale an image, but avoid upscaling it if its dimensions are too low. This can be done using `min` expressions:
    91 
    9287{{{
    9388ffmpeg -i input.jpg -vf "scale='min(320,iw)':'min(240,ih)'" input_not_upscaled.png
     
    9691The output width will be evaluated to be the minimum of 320 and the input width. If you have an imput image that is only 240 pixels wide, the result of the `min` function will be 240 – this will be your target value.
    9792
     93
    9894== Fitting into a Rectangle / Statically-sized Player ==
    9995
     
    10197
    10298You can achieve this with the `force_original_aspect_ratio` option. It has two possible values:
    103 
    10499* `decrease`: The output video dimensions will automatically be decreased if needed.
    105100* `increase`: The output video dimensions will automatically be increased if needed.
    106101
    107102This allows you to force the image to fit into a 320×240 box, downscaling it with the correct aspect ratio:
    108 
    109103{{{
    110104ffmpeg -i input.jpg -vf scale=w=320:h=240:force_original_aspect_ratio=decrease output_320.png
     
    116110
    117111You may have additional constraints such as adding black bars (pillar- and letterboxing) to fill up the remaining space when scaling to a certain rectangle. You can additionally add a black border using the `pad` filter:
    118 
    119112{{{
    120113ffmpeg -i input.jpg -vf "scale=320:240:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2" output_320_padding.png
     
    123116More examples can be found [https://superuser.com/a/1136305/48078 in this Super User answer].
    124117
     118
    125119== scale2ref ==
     120
    126121If you need to scale one video to match another without pre-defining the dimensions, see the [https://ffmpeg.org/ffmpeg-filters.html#scale2ref scale2ref filter].
    127122
    128123Two videos are provided for input and output. The 1st input is scaled and the 2nd input is unchanged, but used for reference. For example, to put 2 videos side-by-side and have the 2nd video scale to match the first:
    129 
    130124{{{
    131125ffmpeg -i vid1.mp4 -i vid2.mp4 -filter_complex "[1:v][0:v]scale2ref=oh*mdar:h=in_h:[v1][v0];[v0][v1]hstack[vo]" -map "[vo]" ./output-video.mp4
     
    136130
    137131You can specify which algorithm is used for resizing with the `-sws_flags` option. For example, to use bilinear instead of the default bicubic scaling:
    138 
    139132{{{
    140133ffmpeg -i test.tif -vf scale=504:376 -sws_flags bilinear out.bmp
     
    154147spline\\
    155148
    156 See the [https://ffmpeg.org/ffmpeg-scaler.html scaler documentation] for more info. 
     149See the [https://ffmpeg.org/ffmpeg-scaler.html scaler documentation] for more info.
    157150
    158 Setting param0 for lanczos is done via
    159 
     151Setting param0 for lanczos is done via
    160152{{{
    161153-vf scale=1920x1080:flags=lanczos:param0=3
     
    164156
    165157To set multiple flags you can combine them with a `+` sign. For example:
    166 
    167 
    168158{{{
    169159-sws_flags lanczos+full_chroma_inp
     
    171161
    172162You can also specify the options directly in the `scale` filter, for example:
    173 
    174163{{{
    175164-vf scale=1920x1080:flags=lanczos
    176165}}}
    177166
     167
    178168== Chroma sample location ==
     169
    179170FFmpeg does not see the chroma sample location on either limited or full range file, so you should specify it by hand when going to .rgb (or upsampled from 4:2:0 to 4:4:4 .yuv):
    180 
    181 
    182171{{{
    183172ffmpeg -i cosmos.mkv -vf 'scale=in_h_chr_pos=0:in_v_chr_pos=128' -pix_fmt rgb24 qnfvarejwnfe3.rgb //for left
     
    186175
    187176To create BT.2020-NCL matrix with top-left chroma this can be used (if the source image is not using bt.2020 primaries the color managment must be done first on linear data, also correct transfer must be tagged, either SDR or HDR one, again this requires color managment):
    188 
    189177{{{
    190178-vf scale=out_color_matrix=bt2020nc:out_h_chr_pos=0:out_v_chr_pos=0
    191179}}}
     180
    192181To change chroma sample location in VUI in HEVC to 0 (left) with -c copy this can be used (2 would be top-left, -1 will remove any sample location from VUI, all 0, 1, 2, 3, 4, 5 sample locations are possible):
    193 
    194182{{{
    195183ffmpeg -i file.mp4 -c copy -bsf:v hevc_metadata=chroma_sample_loc_type=0 file1.mp4