Changes between Version 27 and Version 28 of Scaling
- Timestamp:
- May 3, 2024, 3:20:48 AM (2 years ago)
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].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]. 2 2 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" 5 4 '''Warning:''' 5 * https://trac.ffmpeg.org/ticket/10993 6 6 * 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. 7 7 * 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: … … 17 17 * Dither can be turned off using -vf scale=sws_dither=none 18 18 * 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.60119 * The default for matrix in untagged input and output is always limited BT.601 20 20 }}} 21 21 22 22 In all the examples, the starting image (input.jpg) will be this one (535×346 pixels): 23 [[Image(input.jpg)]] 23 24 24 [[Image(input.jpg)]]25 25 26 26 == Simple Rescaling == … … 35 35 }}} 36 36 The resulting image will look like this: 37 38 37 [[Image(output_320x240.png)]] 39 38 40 39 As you can see, the aspect ratio is not the same as in the original image, so the image appears stretched. 41 40 41 42 42 == Keeping the Aspect Ratio == 43 43 44 44 If 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 46 45 {{{ 47 46 ffmpeg -i input.jpg -vf scale=320:-1 output_320.png 48 47 }}} 48 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. 49 49 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 50 The resulting image will have a dimension of 320×207 pixels. 52 51 [[Image(output_320.png)]] 53 52 54 53 Some 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 56 54 {{{ 57 55 ffmpeg -i input.jpg -vf scale=320:-2 output_320.png 58 56 }}} 57 The output will now be 320×206 pixels. 59 58 60 The output will now be 320×206 pixels.61 59 62 60 == Using Variables == … … 65 63 66 64 For 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 68 65 {{{ 69 66 ffmpeg -i input.jpg -vf "scale=iw*2:ih" input_double_width.png … … 71 68 72 69 The output image will look like this: 73 74 70 [[Image(input_double_width.png)]] 75 71 76 72 If you want to half the size of the picture, just multiply by .5 or divide by 2: 77 78 73 {{{ 79 74 ffmpeg -i input.jpg -vf "scale=iw*.5:ih*.5" input_half_size.png … … 86 81 }}} 87 82 83 88 84 == Avoiding Upscaling == 89 85 90 86 Sometimes you want to scale an image, but avoid upscaling it if its dimensions are too low. This can be done using `min` expressions: 91 92 87 {{{ 93 88 ffmpeg -i input.jpg -vf "scale='min(320,iw)':'min(240,ih)'" input_not_upscaled.png … … 96 91 The 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. 97 92 93 98 94 == Fitting into a Rectangle / Statically-sized Player == 99 95 … … 101 97 102 98 You can achieve this with the `force_original_aspect_ratio` option. It has two possible values: 103 104 99 * `decrease`: The output video dimensions will automatically be decreased if needed. 105 100 * `increase`: The output video dimensions will automatically be increased if needed. 106 101 107 102 This allows you to force the image to fit into a 320×240 box, downscaling it with the correct aspect ratio: 108 109 103 {{{ 110 104 ffmpeg -i input.jpg -vf scale=w=320:h=240:force_original_aspect_ratio=decrease output_320.png … … 116 110 117 111 You 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 119 112 {{{ 120 113 ffmpeg -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 … … 123 116 More examples can be found [https://superuser.com/a/1136305/48078 in this Super User answer]. 124 117 118 125 119 == scale2ref == 120 126 121 If 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]. 127 122 128 123 Two 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 130 124 {{{ 131 125 ffmpeg -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 … … 136 130 137 131 You 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 139 132 {{{ 140 133 ffmpeg -i test.tif -vf scale=504:376 -sws_flags bilinear out.bmp … … 154 147 spline\\ 155 148 156 See the [https://ffmpeg.org/ffmpeg-scaler.html scaler documentation] for more info. 149 See the [https://ffmpeg.org/ffmpeg-scaler.html scaler documentation] for more info. 157 150 158 Setting param0 for lanczos is done via 159 151 Setting param0 for lanczos is done via 160 152 {{{ 161 153 -vf scale=1920x1080:flags=lanczos:param0=3 … … 164 156 165 157 To set multiple flags you can combine them with a `+` sign. For example: 166 167 168 158 {{{ 169 159 -sws_flags lanczos+full_chroma_inp … … 171 161 172 162 You can also specify the options directly in the `scale` filter, for example: 173 174 163 {{{ 175 164 -vf scale=1920x1080:flags=lanczos 176 165 }}} 177 166 167 178 168 == Chroma sample location == 169 179 170 FFmpeg 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 182 171 {{{ 183 172 ffmpeg -i cosmos.mkv -vf 'scale=in_h_chr_pos=0:in_v_chr_pos=128' -pix_fmt rgb24 qnfvarejwnfe3.rgb //for left … … 186 175 187 176 To 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 189 177 {{{ 190 178 -vf scale=out_color_matrix=bt2020nc:out_h_chr_pos=0:out_v_chr_pos=0 191 179 }}} 180 192 181 To 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 194 182 {{{ 195 183 ffmpeg -i file.mp4 -c copy -bsf:v hevc_metadata=chroma_sample_loc_type=0 file1.mp4
