Resize
(Added missing resizers: SincLin2Resize, SinPowerResize, UserDefined2Resize and "force", "keep_center", "placement" parameters) |
|||
| (18 intermediate revisions by 5 users not shown) | |||
| Line 1: | Line 1: | ||
| − | + | <div style="max-width:62em" > | |
| − | {{ | + | <div {{BlueBox2|40|0|3px solid purple}} > |
| + | {{AvsPlusFullname}}<br> | ||
| + | Up-to-date documentation: [https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/resize.html https://avisynthplus.readthedocs.io] | ||
| + | </div> | ||
| − | + | Scales the input video frames to an arbitrary new resolution, and optionally crops the frame before resizing with sub-pixel precision. | |
| − | + | There are trade-offs to be considered between preservation (or augmentation) of image detail and possible artifacts (i.e., oversharpening). | |
| + | </div> | ||
| + | __TOC__ | ||
| − | == | + | == Common Parameters == |
| − | + | {{Par2|target_width, target_height|int|}} | |
| + | :Width and height of the returned clip. | ||
| − | + | {{Par2|src_left, src_top|float|0, 0}} | |
| − | + | :See [[#Cropping |cropping]] discussion below. | |
| + | <div {{ListItemContinue|2}} > | ||
| + | Cropping of the {{FuncArg|left}} and {{FuncArg|top}} edges respectively, in pixels, before resizing. | ||
| + | </div> | ||
| − | + | {{Par2|src_width, src_height|float|(source width, height)}} | |
| + | :See [[#Cropping |cropping]] discussion below. | ||
| + | <div {{ListItemContinue|2}} > | ||
| + | As with [[Crop]], these arguments have different functionality, depending on their value: | ||
| + | * If > zero, these set the '''width''' and '''height''' of the clip before resizing. | ||
| + | * If <= zero, they set the cropping of the '''right''' and '''bottom''' edges respectively, before resizing. | ||
| + | Note, there are certain limits: | ||
| + | * {{FuncArg|clip}}.[[Clip_properties|Width]] must be >= ({{FuncArg|src_left}} + '''width''') | ||
| + | * {{FuncArg|clip}}.[[Clip_properties|Width]] must be > ({{FuncArg|src_left}} + '''right''') | ||
| + | * {{FuncArg|clip}}.[[Clip_properties|Height]] must be >= ({{FuncArg|src_top}} + '''height''') | ||
| + | * {{FuncArg|clip}}.[[Clip_properties|Height]] must be > ({{FuncArg|src_top}} + '''bottom''') | ||
| + | ...otherwise it would enlarge ("un-crop") the clip, or reduce width or height to 0, which is not allowed. | ||
| + | </div> | ||
| − | |||
| − | + | == Cropping == | |
| + | <div style="max-width:62em" > | ||
| + | * All resizers have an expanded syntax which '''crops''' the frame before resizing: | ||
| + | <div {{BoxWidthIndent|54|3}} > | ||
| + | BilinearResize(100, 150, ''src_left''=10, ''src_top''=10, ''src_width''=200, ''src_height''=300) | ||
| + | </div> | ||
| + | <div {{ListItemContinue}} > | ||
| + | ...or more succinctly: | ||
| + | </div> | ||
| + | <div {{BoxWidthIndent|54|3}} > | ||
| + | BilinearResize(100, 150, 10, 10, 200, 300) | ||
| + | </div><div {{ListItemContinue}} > | ||
| + | The operations are the same as if you put [[Crop]] before the Resize: | ||
| + | </div> | ||
| + | <div {{BoxWidthIndent|54|3}} > | ||
| + | Crop(10, 10, 200, 300).BilinearResize(100, 150) | ||
| + | </div> | ||
| − | Note the | + | *Note the cropping parameters are all [[Script_variables|floating point]]. This allows any '''Resize''' filter to be used as a sub-pixel shifter. <sup>[http://forum.doom9.org/showpost.php?p=938102&postcount=2]</sup> |
| + | *Note that [[Crop]] gives a hard boundary, whereas the '''Resize''' filters interpolate pixels outside the cropped region – depending on the resizer kernel – bilinear, bicubic etc, and not beyond the edge of the image. | ||
| − | + | *As a general rule, | |
| − | + | ** [[Crop]] any hard borders or noise; '''Resize''' cropping may propagate the noise into the output. | |
| + | ** Use '''Resize''' cropping to maintain accurate edge rendering when excising a part of a complete image. | ||
| − | + | *Negative cropping is allowed; this results in repeated edge pixels as shown below: | |
| + | <div {{BoxWidthIndent|54|3}} > | ||
| + | BilinearResize(Width, Height, -64, -64, Width, Height) | ||
| + | </div> | ||
| + | :[[File:Sintel_frm6291_Resize_shift.jpg|680px]] | ||
| + | </div> | ||
| − | |||
| − | + | == BilinearResize == | |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |BilinearResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | '''BilinearResize''' uses standard [[Wikipedia:Bilinear_filtering|bilinear filtering]] and is a good choice for smoothing overly sharp sources. | |
| + | </div> | ||
| − | |||
| − | + | == BicubicResize == | |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |BicubicResize(clip ''clip'', int ''target_width'', int ''target_height'' [, float ''b'', float ''c'', <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | '''BicubicResize''' is similar to [[#BilinearResize|BilinearResize]], except that instead of a linear filtering function it uses the [[Wikipedia:Mitchell–Netravali_filters|Mitchell–Netravali]] two-part cubic. The parameters {{FuncArg|b}} and {{FuncArg|c}} can be used to adjust the properties of the cubic; they are sometimes referred to as "blurring" and "ringing" respectively. | |
| − | ''' | + | If you are enlarging your video, you will get sharper results with '''BicubicResize''' than with BilinearResize. However, if you are shrinking it, you may prefer [[#BilinearResize|BilinearResize]] as it performs some [[Wikipedia:Spatial_anti-aliasing#Examples|antialiasing]]. |
| − | + | ==== parameters ''b'' and ''c'' ==== | |
| − | + | {{Par2|b, c|float|1/3}} | |
| + | :The default for both {{FuncArg|b}} and {{FuncArg|c}} is 1/3, which were recommended by Mitchell and Netravali for having the most visually pleasing results. | ||
| − | + | <div {{ListItemContinue|2}} > | |
| − | + | Set [{{FuncArg|b}} + 2{{FuncArg|c}} = 1] for the most numerically accurate filter. This gives, for {{FuncArg|b}}=0, the maximum value of 0.5 for {{FuncArg|c}}, which is the [[Wikipedia:Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline|Catmull-Rom spline]] and a good suggestion for sharpness. | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | Larger values of {{FuncArg|b}} and {{FuncArg|c}} can produce interesting op-art effects – for example, try ({{FuncArg|b}}=0, {{FuncArg|c}}= -5.0). | |
| − | + | ||
| − | + | ||
| − | = | + | As {{FuncArg|c}} exceeds 0.6, the filter starts to [[Wikipedia:Ringing_artifacts|"ring"]] or overshoot. You won't get true sharpness – what you'll get is exaggerated edges. |
| + | Negative values for {{FuncArg|b}} (although allowed) give undesirable results, so use {{FuncArg|b}}=0 for values of {{FuncArg|c}} > 0.5. | ||
| − | + | With ({{FuncArg|b}}=0, {{FuncArg|c}}=0.75) the filter is the same as [http://www.virtualdub.org/blog/pivot/entry.php?id=95 VirtualDub's "Precise Bicubic"]. | |
| − | + | '''BicubicResize''' may be the most visually pleasing of the '''Resize''' filters for ''downsizing'' to half-size or less.<sup>[http://forum.doom9.org/showthread.php?t=172871&page=2 doom9]</sup><br>Try the default setting, ({{FuncArg|b}}=0, {{FuncArg|c}}=0.75) as above, or ({{FuncArg|b}}= -0.5, {{FuncArg|c}}=0.25). | |
| + | </div> | ||
| + | </div> | ||
| − | + | == BlackmanResize == | |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |BlackmanResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''taps'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | '''BlackmanResize''' is a modification of LanczosResize that has better control of [[Wikipedia:Ringing_artifacts|ringing]] artifacts for high numbers of {{FuncArg|taps}}. | |
| − | + | ==== parameter ''taps'' ==== | |
| − | + | {{Par2|taps|int|4}} | |
| + | :See [[#lanczos_taps|LanczosResize]] for an explanation of the {{FuncArg|taps}} argument (default 4, range 1-100). | ||
| + | </div> | ||
| − | |||
| − | ''' | + | == GaussResize == |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |GaussResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', float ''p'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | '''GaussResize''' uses a [[Wikipedia:Gaussian_filter|gaussian]] resizer, which unlike the bicubics, does not overshoot – but perhaps does not appear as sharp to the eye. | |
| − | + | ==== parameter ''p'' ==== | |
| + | {{Par2|p|float|30.0}} | ||
| + | :Sharpness. Range from about 1 to 100, with 1 being very blurry and 100 being very sharp. | ||
| + | </div> | ||
| − | |||
| − | ''' | + | == LanczosResize == |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |LanczosResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''taps'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | {{FuncDef | |
| + | |Lanczos4Resize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | '''LanczosResize''' is a sharper alternative to [[#BicubicResize|BicubicResize]]. It is NOT suited for low bitrate video; the various Bicubic flavours are much better for this. | |
| − | '''Lanczos4Resize''' is a short hand for LanczosResize(taps=4). It produces sharper images than LanczosResize with the default taps=3, especially useful when upsizing a clip. | + | '''Lanczos4Resize''' is a short hand for <code>LanczosResize(taps=4)</code>. It produces sharper images than LanczosResize with the default {{FuncArg|taps}}=3, especially useful when upsizing a clip. |
| − | '' | + | <div id="lanczos_taps" style="display:inline;font-size:50%;height:0;line-height:0;overflow:hidden;"></div> |
| + | ==== parameter ''taps'' ==== | ||
| + | {{Par2|taps|int|3}} | ||
| + | :Basically, {{FuncArg|taps}} affects sharpness. Default 3, range 1-100. Equal to the number of filter [[Wikipedia:Lanczos_resampling#Lanczos_kernel|''lobes'']] (ignoring mirroring around the origin). | ||
| − | + | <div {{ListItemContinue|2}} > | |
| + | ''Note:'' the input argument named {{FuncArg|taps}} should really be called "lobes". When discussing resizers, "taps" has a different meaning, as described below: | ||
| − | + | <div {{ListItemContinue|1}} > | |
| + | {{BoldColor|black|120|“}}So when people talk about Lanczos2, they mean a 2-lobe Lanczos-windowed sinc function. There are actually 4 lobes -- 2 on each side... | ||
| − | + | For upsampling (making the image larger), the filter is sized such that the entire equation falls across 4 input samples, making it a 4-tap filter. It doesn't matter how big the output image is going to be - it's still just 4 taps. For downsampling (making the image smaller), the equation is sized so it will fall across 4 *destination* samples, which obviously are spaced at wider intervals than the source samples. So for downsampling by a factor of 2 (making the image half as big), the filter covers 8 input samples, and thus 8 taps. For 3X downsampling, you need 12 taps, and so forth. | |
| − | + | The total number of taps you need for downsampling is the downsampling ratio times the number of lobes, times 2. And practically, one needs to round that up to the next even integer. For upsampling, it's always 4 taps.{{BoldColor|black|120|”}} | |
| − | + | [http://www.avsforum.com/forum/26-home-theater-computers/460922-lanczos-vs-bicubic-comparison-2.html#post4760581 Don Munsil (avsforum post)] | [[lanczos lobs/taps|mirror]]. | |
| + | </div> | ||
| + | </div> | ||
| + | </div> | ||
| − | |||
| − | ''' | + | == PointResize == |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |PointResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | '''PointResize''' is the simplest resizer possible. It uses a Point Sampler or [[Wikipedia:Nearest-neighbor_interpolation|Nearest Neighbour]] algorithm, which usually results in a very "blocky" image. So in general this filter should only be used, if you ''intend'' to have inferior quality, or you need the clear pixel drawings. Useful for magnifying small areas for examination. | |
| + | </div> | ||
| − | |||
| − | ''' | + | == Spline based resizers == |
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |Spline16Resize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| − | + | {{FuncDef | |
| − | + | |Spline36Resize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | |
| − | + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | |
| + | }} | ||
| − | + | {{FuncDef | |
| + | |Spline64Resize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| + | '''Spline16Resize''', '''Spline36Resize''' and '''Spline64Resize''' are three [[Wikipedia:Spline_interpolation|Spline based]] resizers. They are the (cubic) spline based resizers from [http://sourceforge.net/projects/panotools/ Panorama tools] that fit a spline through the sample points and then derives the filter kernel from the resulting blending polynomials. See [http://forum.doom9.org/showthread.php?t=147117 this thread] for the technical details. | ||
| + | |||
| + | The rationale for '''Spline''' is to be as sharp as possible with less ringing artifacts than [[#LanczosResize|LanczosResize]] produces. '''Spline16Resize''' uses √16 or 4 sample points, '''Spline36Resize''' uses √36 or 6 sample points, etc ... The more sample points used, the more accurate the resampling. Several resizer comparison pages are given in the [[#External Links|External Links]] section. | ||
| + | |||
| + | *'''Spline64Resize''' may be the most accurate of the '''Resize''' filters.<sup>[http://web.archive.org/web/20060827184031/http://www.path.unimelb.edu.au/~dersch/interpolator/interpolator.html Dersch]</sup> | ||
| + | *'''Spline16Resize''' is sharper and [[Wikipedia:Ringing_artifacts|rings]] just a bit (which may be desirable with soft sources),<br>and looks pleasing to the eye when enlarging or reducing in moderate amounts.<sup>[http://forum.doom9.org/showthread.php?p=1689519#post1689519 doom9]</sup> | ||
| + | *'''Spline36Resize''' is somewhere in between the other two. | ||
| + | </div> | ||
| + | |||
| + | |||
| + | == SincResize == | ||
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |SincResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''taps'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| + | |||
| + | '''SincResize''' uses the truncated sinc function. It is very sharp, but prone to [[Wikipedia:Ringing_artifacts|ringing]] artifacts. | ||
| + | |||
| + | ==== parameter ''taps'' ==== | ||
| + | {{Par2|taps|int|4}} | ||
| + | :See [[#lanczos_taps|LanczosResize]] for an explanation of the {{FuncArg|taps}} argument (default 4, range 1-20). | ||
| + | </div> | ||
| + | |||
| + | == SincLin2Resize == | ||
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |SincLin2Resize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''taps'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| + | |||
| + | '''SincLin2Resize''' is a high-quality resizer that supplements SincResize, designed to maintain performance with increased sinc taps for minimal artifacts. This is a version of SincResize with a workaround for the 'kernel edge computing issue' present in the original SincResize kernel. It is slightly sharper compared to other weighted sinc kernels with the same number of taps (such as Lanczos or Blackman). To suppress computing errors below 1 LSB of 8-bit, a recommended number of taps is greater than 3 or 4. Using too few taps may still expose this issue. For higher precision computing (greater than 8-bit per sample), the minimum number of taps required to shift residual computing errors below 1 LSB may be higher. | ||
| + | |||
| + | </div> | ||
| + | |||
| + | == SinPowerResize == | ||
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |SinPowerResize(clip ''clip'', int ''target_width'', int ''target_height'' [, <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', float ''p'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| + | |||
| + | '''SinPowerResize''' is an easy-to-adjust resizer with a single control parameter, perfect for downsampling and creating content conditioned to reduce aliasing and ringing. Both SinPow and UserDefined2 resizers allow control over the acutance effect of the output while minimizing excessive ringing (within a certain range of control parameters). Acutance of the Gauss kernel can be considered the 'zero level,' whereas for SinPow and UserDefined2, it can be greater than zero, depending on the control parameters. | ||
| + | |||
| + | == UserDefined2Resize == | ||
| + | <div style="max-width:62em" > | ||
| + | {{FuncDef | ||
| + | |UserDefined2Resize(clip ''clip'', int ''target_width'', int ''target_height'' [, float ''b'', float ''c'', float ''s'', <br> | ||
| + | float ''src_left'', float ''src_top'', float ''src_width'', float ''src_height'', int ''force'', bool ''keep_center'', string ''placement'' ] ) | ||
| + | }} | ||
| + | |||
| + | '''UserDefined2Resize''' is a versatile resizer offering fine control over sharpness and ringing, ideal for downsampling and high-quality antialiasing with adjustable parameters. | ||
| + | |||
| + | |||
| + | |||
| + | == Examples == | ||
| + | * Cropping: | ||
| + | <div {{BoxWidthIndent|42|3}} > | ||
| + | Crop(10, 10, 200, 300).BilinearResize(100, 150) | ||
| + | </div> | ||
| + | <div {{ListItemContinue}} > | ||
| + | which is nearly the same as: | ||
| + | </div> | ||
| + | <div {{BoxWidthIndent|42|3}} > | ||
| + | BilinearResize(100, 150, 10, 10, 200, 300) | ||
| + | </div> | ||
| + | |||
| + | * Load a video file and resize it to 240x180 (from whatever it was before) | ||
| + | <div {{BoxWidthIndent|42|3}} > | ||
| + | AviSource("video.avi").BilinearResize(240,180) | ||
| + | </div> | ||
| + | |||
| + | * Load a 720x480 ([[Wikipedia:Rec._601|Rec. 601]]) video and resize it to 352x240 ([[Wikipedia:Video_CD|VCD]]), preserving the correct aspect ratio | ||
| + | <div {{BoxWidthIndent|42|3}} > | ||
| + | AviSource("dv.avi").BilinearResize(352, 240, 8, 0, 704, 480) | ||
| + | </div> | ||
| + | <div {{ListItemContinue}} > | ||
| + | which is the same as: | ||
| + | </div> | ||
| + | <div {{BoxWidthIndent|42|3}} > | ||
| + | AviSource("dv.avi").BilinearResize(352, 240, 8, 0, -8, -0) | ||
| + | </div> | ||
| + | |||
| + | * Extract the upper-right quadrant of a 320x240 video and zoom it to fill the whole frame | ||
| + | <div {{BoxWidthIndent|42|3}} > | ||
| + | BilinearResize(320, 240, 160, 0, 160, 120) | ||
| + | </div> | ||
| + | |||
| + | |||
| + | == Notes == | ||
| + | <div style="max-width:62em" > | ||
| + | * AviSynth has completely separate vertical and horizontal resizers. If input is the same as output on one axis, that resizer will be skipped. The resizer with the smallest downscale ratio is called first; this is done to preserve maximum quality, so the second resizer has the best possible picture to work with. [[Filter_SDK/Data_storage|Data storing]] will have an impact on what [[Modulo|mods]] should be used for sizes when resizing and cropping; see [[Crop#Crop restrictions|Crop restrictions]]. | ||
| + | </div> | ||
| + | |||
| + | |||
| + | == External Links == | ||
| + | * [http://hermidownloads.craqstar.de/videoresizefiltercomparasion/ ''AviSynth resize filter comparison''] (hermidownloads.craqstar.de) | [http://web.archive.org/web/20130815024055/http://hermidownloads.craqstar.de/videoresizefiltercomparasion archived link] | ||
| + | * [http://jeanbruenn.info/2011/10/30/upscaling-in-avisynth-comparison-of-resizers/ ''Upscaling in Avisynth – Comparison of resizers''] (jeanbruenn.info) | [http://web.archive.org/web/20140207171106/http://jeanbruenn.info/2011/10/30/upscaling-in-avisynth-comparison-of-resizers/ archived link] | ||
| + | * [http://web.archive.org/web/20060827184031/http://www.path.unimelb.edu.au/~dersch/interpolator/interpolator.html ''Testing Interpolator Quality''] (Helmut Dersch, Technical University Furtwangen) | ||
| + | * [http://forum.doom9.org/showthread.php?t=172871 ''Discussion of resizers for downsizing''] (doom9.org) | ||
| + | |||
| + | |||
| + | == Changelog == | ||
{| border="1" | {| border="1" | ||
| + | |- | ||
| + | | v3.7.4 | ||
| + | | Added "force", "keep_center", "placement" parameters. | ||
| + | |- | ||
| + | | v3.7.3 | ||
| + | | Added SinPowerResize, SincLin2Resize, UserDefined2Resize. | ||
|- | |- | ||
| v2.60 | | v2.60 | ||
| Line 131: | Line 332: | ||
[[Category:Internal filters]] | [[Category:Internal filters]] | ||
| + | [[Category:Resizers]] | ||
Latest revision as of 14:03, 11 January 2026
AviSynth+
Up-to-date documentation: https://avisynthplus.readthedocs.io
Scales the input video frames to an arbitrary new resolution, and optionally crops the frame before resizing with sub-pixel precision.
There are trade-offs to be considered between preservation (or augmentation) of image detail and possible artifacts (i.e., oversharpening).
Contents |
[edit] Common Parameters
int target_width, target_height =
- Width and height of the returned clip.
float src_left, src_top = 0, 0
- See cropping discussion below.
Cropping of the left and top edges respectively, in pixels, before resizing.
float src_width, src_height = (source width, height)
- See cropping discussion below.
As with Crop, these arguments have different functionality, depending on their value:
- If > zero, these set the width and height of the clip before resizing.
- If <= zero, they set the cropping of the right and bottom edges respectively, before resizing.
Note, there are certain limits:
- clip.Width must be >= (src_left + width)
- clip.Width must be > (src_left + right)
- clip.Height must be >= (src_top + height)
- clip.Height must be > (src_top + bottom)
...otherwise it would enlarge ("un-crop") the clip, or reduce width or height to 0, which is not allowed.
[edit] Cropping
- All resizers have an expanded syntax which crops the frame before resizing:
BilinearResize(100, 150, src_left=10, src_top=10, src_width=200, src_height=300)
...or more succinctly:
BilinearResize(100, 150, 10, 10, 200, 300)
The operations are the same as if you put Crop before the Resize:
Crop(10, 10, 200, 300).BilinearResize(100, 150)
- Note the cropping parameters are all floating point. This allows any Resize filter to be used as a sub-pixel shifter. [1]
- Note that Crop gives a hard boundary, whereas the Resize filters interpolate pixels outside the cropped region – depending on the resizer kernel – bilinear, bicubic etc, and not beyond the edge of the image.
- As a general rule,
- Crop any hard borders or noise; Resize cropping may propagate the noise into the output.
- Use Resize cropping to maintain accurate edge rendering when excising a part of a complete image.
- Negative cropping is allowed; this results in repeated edge pixels as shown below:
BilinearResize(Width, Height, -64, -64, Width, Height)
[edit] BilinearResize
BilinearResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
BilinearResize uses standard bilinear filtering and is a good choice for smoothing overly sharp sources.
[edit] BicubicResize
BicubicResize(clip clip, int target_width, int target_height [, float b, float c,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
BicubicResize is similar to BilinearResize, except that instead of a linear filtering function it uses the Mitchell–Netravali two-part cubic. The parameters b and c can be used to adjust the properties of the cubic; they are sometimes referred to as "blurring" and "ringing" respectively.
If you are enlarging your video, you will get sharper results with BicubicResize than with BilinearResize. However, if you are shrinking it, you may prefer BilinearResize as it performs some antialiasing.
[edit] parameters b and c
float b, c = 1/3
- The default for both b and c is 1/3, which were recommended by Mitchell and Netravali for having the most visually pleasing results.
Set [b + 2c = 1] for the most numerically accurate filter. This gives, for b=0, the maximum value of 0.5 for c, which is the Catmull-Rom spline and a good suggestion for sharpness.
Larger values of b and c can produce interesting op-art effects – for example, try (b=0, c= -5.0).
As c exceeds 0.6, the filter starts to "ring" or overshoot. You won't get true sharpness – what you'll get is exaggerated edges. Negative values for b (although allowed) give undesirable results, so use b=0 for values of c > 0.5.
With (b=0, c=0.75) the filter is the same as VirtualDub's "Precise Bicubic".
BicubicResize may be the most visually pleasing of the Resize filters for downsizing to half-size or less.doom9
Try the default setting, (b=0, c=0.75) as above, or (b= -0.5, c=0.25).
[edit] BlackmanResize
BlackmanResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int taps, int force, bool keep_center, string placement ] )
BlackmanResize is a modification of LanczosResize that has better control of ringing artifacts for high numbers of taps.
[edit] parameter taps
int taps = 4
- See LanczosResize for an explanation of the taps argument (default 4, range 1-100).
[edit] GaussResize
GaussResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, float p, int force, bool keep_center, string placement ] )
GaussResize uses a gaussian resizer, which unlike the bicubics, does not overshoot – but perhaps does not appear as sharp to the eye.
[edit] parameter p
float p = 30.0
- Sharpness. Range from about 1 to 100, with 1 being very blurry and 100 being very sharp.
[edit] LanczosResize
LanczosResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int taps, int force, bool keep_center, string placement ] )
Lanczos4Resize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
LanczosResize is a sharper alternative to BicubicResize. It is NOT suited for low bitrate video; the various Bicubic flavours are much better for this.
Lanczos4Resize is a short hand for LanczosResize(taps=4). It produces sharper images than LanczosResize with the default taps=3, especially useful when upsizing a clip.
[edit] parameter taps
int taps = 3
- Basically, taps affects sharpness. Default 3, range 1-100. Equal to the number of filter lobes (ignoring mirroring around the origin).
Note: the input argument named taps should really be called "lobes". When discussing resizers, "taps" has a different meaning, as described below:
“So when people talk about Lanczos2, they mean a 2-lobe Lanczos-windowed sinc function. There are actually 4 lobes -- 2 on each side...
For upsampling (making the image larger), the filter is sized such that the entire equation falls across 4 input samples, making it a 4-tap filter. It doesn't matter how big the output image is going to be - it's still just 4 taps. For downsampling (making the image smaller), the equation is sized so it will fall across 4 *destination* samples, which obviously are spaced at wider intervals than the source samples. So for downsampling by a factor of 2 (making the image half as big), the filter covers 8 input samples, and thus 8 taps. For 3X downsampling, you need 12 taps, and so forth.
The total number of taps you need for downsampling is the downsampling ratio times the number of lobes, times 2. And practically, one needs to round that up to the next even integer. For upsampling, it's always 4 taps.”
[edit] PointResize
PointResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
PointResize is the simplest resizer possible. It uses a Point Sampler or Nearest Neighbour algorithm, which usually results in a very "blocky" image. So in general this filter should only be used, if you intend to have inferior quality, or you need the clear pixel drawings. Useful for magnifying small areas for examination.
[edit] Spline based resizers
Spline16Resize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
Spline36Resize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
Spline64Resize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
Spline16Resize, Spline36Resize and Spline64Resize are three Spline based resizers. They are the (cubic) spline based resizers from Panorama tools that fit a spline through the sample points and then derives the filter kernel from the resulting blending polynomials. See this thread for the technical details.
The rationale for Spline is to be as sharp as possible with less ringing artifacts than LanczosResize produces. Spline16Resize uses √16 or 4 sample points, Spline36Resize uses √36 or 6 sample points, etc ... The more sample points used, the more accurate the resampling. Several resizer comparison pages are given in the External Links section.
[edit] SincResize
SincResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int taps, int force, bool keep_center, string placement ] )
SincResize uses the truncated sinc function. It is very sharp, but prone to ringing artifacts.
[edit] parameter taps
int taps = 4
- See LanczosResize for an explanation of the taps argument (default 4, range 1-20).
[edit] SincLin2Resize
SincLin2Resize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, int taps, int force, bool keep_center, string placement ] )
SincLin2Resize is a high-quality resizer that supplements SincResize, designed to maintain performance with increased sinc taps for minimal artifacts. This is a version of SincResize with a workaround for the 'kernel edge computing issue' present in the original SincResize kernel. It is slightly sharper compared to other weighted sinc kernels with the same number of taps (such as Lanczos or Blackman). To suppress computing errors below 1 LSB of 8-bit, a recommended number of taps is greater than 3 or 4. Using too few taps may still expose this issue. For higher precision computing (greater than 8-bit per sample), the minimum number of taps required to shift residual computing errors below 1 LSB may be higher.
[edit] SinPowerResize
SinPowerResize(clip clip, int target_width, int target_height [,
float src_left, float src_top, float src_width, float src_height, float p, int force, bool keep_center, string placement ] )
SinPowerResize is an easy-to-adjust resizer with a single control parameter, perfect for downsampling and creating content conditioned to reduce aliasing and ringing. Both SinPow and UserDefined2 resizers allow control over the acutance effect of the output while minimizing excessive ringing (within a certain range of control parameters). Acutance of the Gauss kernel can be considered the 'zero level,' whereas for SinPow and UserDefined2, it can be greater than zero, depending on the control parameters.
[edit] UserDefined2Resize
UserDefined2Resize(clip clip, int target_width, int target_height [, float b, float c, float s,
float src_left, float src_top, float src_width, float src_height, int force, bool keep_center, string placement ] )
UserDefined2Resize is a versatile resizer offering fine control over sharpness and ringing, ideal for downsampling and high-quality antialiasing with adjustable parameters.
[edit] Examples
- Cropping:
Crop(10, 10, 200, 300).BilinearResize(100, 150)
which is nearly the same as:
BilinearResize(100, 150, 10, 10, 200, 300)
- Load a video file and resize it to 240x180 (from whatever it was before)
AviSource("video.avi").BilinearResize(240,180)
AviSource("dv.avi").BilinearResize(352, 240, 8, 0, 704, 480)
which is the same as:
AviSource("dv.avi").BilinearResize(352, 240, 8, 0, -8, -0)
- Extract the upper-right quadrant of a 320x240 video and zoom it to fill the whole frame
BilinearResize(320, 240, 160, 0, 160, 120)
[edit] Notes
- AviSynth has completely separate vertical and horizontal resizers. If input is the same as output on one axis, that resizer will be skipped. The resizer with the smallest downscale ratio is called first; this is done to preserve maximum quality, so the second resizer has the best possible picture to work with. Data storing will have an impact on what mods should be used for sizes when resizing and cropping; see Crop restrictions.
[edit] External Links
- AviSynth resize filter comparison (hermidownloads.craqstar.de) | archived link
- Upscaling in Avisynth – Comparison of resizers (jeanbruenn.info) | archived link
- Testing Interpolator Quality (Helmut Dersch, Technical University Furtwangen)
- Discussion of resizers for downsizing (doom9.org)
[edit] Changelog
| v3.7.4 | Added "force", "keep_center", "placement" parameters. |
| v3.7.3 | Added SinPowerResize, SincLin2Resize, UserDefined2Resize. |
| v2.60 | Added SincResize. |
| v2.58 | Added BlackmanResize, Spline64Resize. |
| v2.56 | Added Spline16Resize, Spline36Resize, GaussResize and taps parameter in LanczosResize; added offsets in Crop part of xxxResize. |
| v2.55 | Added Lanczos4Resize. |