Log in

View Full Version : CropResize - Cropping & resizing function (Avisynth & VapourSynth versions)


Pages : [1] 2 3

hello_hello
15th July 2019, 18:43
From the version dated 2023-09-28 there's a native VapourSynth flavour of CropResize.

Quite a few changes have been introduced in the version dated 2025-06-16, so if you've used the function in the past the Changes text file would be worth reading. The main change to note for the Avisynth version of CropResize is Avisynth+ 3.7.1 is now a minimum requirement.

The main change for the version dated 2025-12-20 is the inclusion of a new function, CombineClips, that uses CropResize to automatically append videos. See post #97 (https://forum.doom9.org/showthread.php?p=2026204#post2026204) for usage examples.

CropResize 2025-12-20.zip (https://files.videohelp.com/u/210984/CropResize%202025-12-20.zip)

The purpose of the script
The main goal of CropResize is to crop and resize without having to worry about calculating aspect error or distorting the picture. Rather than distort the picture as traditional resizing does when the input and output aspect ratios don't match, the script crops or adds borders instead. It can apply sub-pixel cropping when required.
Despite the numerous options, basic usage is fairly straightforward.

The pictures in post #2 illustrate CropResize usage.

hello_hello
15th July 2019, 18:44
The easiest way to demonstrate CropResize is with some pictures

Some of these examples also demonstrate using the wrapper functions supplied with CropResize to easily
enable the default cropping preview or set Info=true, and some also use the abbreviated function name of CR().

The (home made) PAL 16:9 source used for the following examples

https://i.postimg.cc/Zns9Tsb9/Crop-Resize-01-PAL-16-9.jpg


Basic usage
Simply specify a width (or height) and the desired cropping (or enable auto-cropping), along with the input display
aspect ratio if the source is anamorphic, and let CropResize take care of the rest, here resizing to "square pixel" dimensions.
The abbreviated function name CR() can be used instead of CropResize() if the wrapper functions script is loaded.

CropResize(832,0, 4,32,-6,-32, InDAR=16.0/9.0, Info=true)
or
CR(832,0, 4,32,-6,-32, InDAR=16.0/9.0, Info=true)

https://i.postimg.cc/zfYyXgrk/Crop-Resize-02-Specify-Width.jpg


Cropping according to the output dimensions
When specifying both an output width and height, and borders aren't enabled, the script crops accordingly to prevent
aspect error (although specifying an OutDAR takes precedence over the cropping and output display aspect ratio).
Simply to demonstrate, here 16:9 output dimensions are specified.

CropResize(832,468, 4,32,-6,-32, InDAR=16.0/9.0, Info=true)

https://i.postimg.cc/W4mhD1pc/Crop-Resize-03-Specify-Width-Height-16-9.jpg


Adding borders according to the output dimensions
When specifying both an output width and height, and borders are enabled, the script adds pillarbox or letterbox
borders as required instead of cropping picture (a small amount of extra cropping may still be applied to prevent
aspect error). As for the previous example, 16:9 output dimensions are specified.

CropResize(832,468, 4,32,-6,-32, InDAR=16.0/9.0, Borders=true, Info=true)

https://i.postimg.cc/nzHMqfMj/Crop-Resize-04-Specify-Width-Height-Borders.jpg


MeGUI support
MeGUI was used to crop the source, adding it's global DAR variables and cropping to the script.
CropResize then takes care of the resizing and any extra cropping required to prevent aspect error.

global MeGUI_darx = 71
global MeGUI_dary = 36
Crop(4,32,-6,-32)
CropResize(832,0, Info=true)

https://i.postimg.cc/mkkD63YT/Crop-Resize-05-Me-GUI.jpg


Specifying an output display aspect ratio and adding borders
Cropping and resizing to NTSC dimensions with an mpeg4 display aspect ratio of 20:11 (including the added borders).

CropResize(720,480, 4,32,-6,-32, InDAR=16.0/9.0, OutDAR=20.0/11.0, Borders=true, Info=true)

https://i.postimg.cc/SsDRr1zZ/Crop-Resize-06-NTSC-20-11.jpg


Cropping according to the output display aspect ratio
When an output display aspect ratio is specified and borders aren't enabled, the script adjusts the
cropping to crop to that display aspect ratio and resizes to the specified width and height.
Here the picture is cropped to 16:9 and resized to NTSC 720x480 dimensions.

Exactly the same result can be achieved with the appropriate output sample (pixel) aspect ratio instead of
a display aspect ratio. In this case it'd be 32:37.

CropResize(720,480, 4,32,-6,-32, InDAR=16.0/9.0, OutDAR=16.0/9.0, Info=true)
or
CropResize(720,480, 4,32,-6,-32, InDAR=16.0/9.0, OutSAR=32.0/27.0, Info=true)

https://i.postimg.cc/J0FnwyxZ/Crop-Resize-07-NTSC-16-9.jpg


Resize Width Only
For the purists, there's a "Resize Width Only" mode, preventing height resizing.
It's mainly intended for anamorphic sources and supports anamorphic input/output,
but here there's no output display aspect ratio specified, so the script is automatically
cropping and resizing the width to "square pixel" dimensions.
The function name is preceded with "i" to set Info=true

iCR(0,0, 4,32,-6,-32, InDAR=16.0/9.0, ResizeWO=true)

https://i.postimg.cc/jq3Cn9T2/Crop-Resize-08-Resize-Width-Only.jpg


No Resizing
Resizing can also be disabled completely so the function only crops (it can still add borders though).

CropResize(0,0, 4,32,-6,-32, InDAR=16.0/9.0, NoResize=true, Info=true)

https://i.postimg.cc/CLZ5GNMN/Crop-Resize-09-No-Resizing.jpg


Color conversion
Probably a bit hard to see the difference here, but in addition to automatic color correction,
the ColorMode argument permits specifying a color conversion.

CropResize(832,0, 4,32,-6,-32, InDAR=16.0/9.0, ColorConvert="HDRMatrix", ColorMode="709-601", Info=true)

https://i.postimg.cc/BbjSCS36/Crop-Resize-10-Color-Conversion.jpg


Cropping previews
Output dimensions of 16:9 are specified without borders enabled (832x468) but the specified cropping
is not enough to crop the picture to 16:9, so the script must crop extra from the sides.
The yellow lines show the cropping specified by the user.
The blue lines show any additional cropping applied by the script to prevent aspect error.

The default cropping preview can be enabled by preceding the function name with "p".
pCropResize(832,468, 4,32,-6,-32, InDAR=16.0/9.0)
or
pCR(832,468, 4,32,-6,-32, InDAR=16.0/9.0)
or
CropResize(832,468, 4,32,-6,-32, InDAR=16.0/9.0, CPreview=1)

Also note: Preceding the function name with "pi" enables both the default cropping preview and sets Info=true,
assuming the wrapper functions script is loaded.

https://i.postimg.cc/pdvdtMfG/Crop-Resize-11-CPreview-1.jpg


CropResize(832,468, 4,32,-6,-32, InDAR=16.0/9.0, CPreview=2)

https://i.postimg.cc/4dL4tKrq/Crop-Resize-12-CPreview-2.jpg


CropResize(832,468, 4,32,-6,-32, InDAR=16.0/9.0, CPreview=3)
An AvsPmod style preview.

https://i.postimg.cc/9fBQmg1W/Crop-Resize-13-CPreview-3.jpg


FrostyBorders
CropDAR used to force a cropping of 4:3, with 16:9 output dimensions to demonstrate adding FrostyBorders.

CR(832,468, 4,32,-6,-32, CropDAR=4.0/3.0, InDAR=16.0/9.0, Frosty=true)

https://i.postimg.cc/vTpsLCGw/Crop-Resize-14-Frosty-Borders.jpg

hello_hello
16th July 2019, 00:49
As is always the case, I found a minor gremlin not long after creating this thread. Sometimes Info=true wasn't displaying the output sample aspect ratio when resizing was disabled. The link in the opening post has been updated. The fixed version is dated 2019-07-17.

hello_hello
7th August 2019, 20:57
There's a new version of CropResize (2019-08-08). The link in the opening post has been updated.
The changes are aimed at making the script's behaviour more predictable, although there's not a lot of them. The cropping and resizing functionality remains the same. There's a list of changes in the zip file.

FranceBB
7th August 2019, 22:14
Thank you!! :D

Just one thing:

ColorCorrection (removed)
CropResize no longer converts the colors when upscaling or downscaling.
It previously only converted between rec.601 and rec.709, and color conversion isn't technically the job of a cropping/resizing script, so color correction has been removed entirely.

Instead of removing it entirely, why don't you add it as a bool option which is "false" (disabled) by default? I think that it can be useful in automatized workflows used by some people, so if they want to, they should be able to turn it on.
That's just what I had in mind, anyway, nice resizing script, thank you! :D

hello_hello
7th August 2019, 23:13
Thank you!! :D

Just one thing:



Instead of removing it entirely, why don't you add it as a bool option which is "false" (disabled) by default? I think that it can be useful in automatized workflows used by some people, so if they want to, they should be able to turn it on.
That's just what I had in mind, anyway, nice resizing script, thank you! :D

I actually prefer to include it myself, but there's more colorspaces now, and UHD, which I never work with, so I thought maybe it was best if the script just stuck to cropping and resizing. Plus when I added it originally I had it enabled by default due to my color conversion OCD, but not everyone was crazy about that.

As I prefer it though, I added it back to a version of the script for myself. It still only converts between HD and SD with ColorMatrix.dll, but unlike the previous version it doesn't convert when the source or destination resolution exceed 1080p.
Because it was for me I didn't add an argument for it, but I included a way to disable it by changing a line about 12 lines from the bottom of the script, along with some of the other defaults. It looks like this:

function CR_ColorCorrect() { return true }

If you want a version with a function argument, it shouldn't be too hard to add it back. Anyway, here's a link for my ColorMatrix version.

Edit. Link removed. See post #8.

Aside from the color conversion, everything else is the same, including the function name.

So you know what the rules are, it automatically color converts when downscaling if the source "display" width is > 1056 or the source height is >= 600 and the destination "display" width is <= 1056 and the destination height is < 600.
Upscaling the rules are the same for source and destination width and height.
Info=true will still tell you when color conversion is taking place.

FranceBB
8th August 2019, 13:36
Got it.
Thank you for clarifying and sharing your modified personal version as well! :)

hello_hello
9th August 2019, 00:12
FranceBB,
as it turns out, you talked me into it. Color conversion has been added back to the "official" version. It's now dated 2019-08-09. I'll update the link in the opening post shortly.

I've added back the ColorCorrect argument, but rather than true or false, 0 is disabled, 1 converts with ColorMatrix.dll, and 2 converts with DitherTools. Conversion between SD, HD and UHD colorimetry is now supported.
I don't think there's a 64 bit version of ColorMatrix with Rec.2020 support, but the included 32 bit version has it. It supports YV12 & YUY2.
DitherTools supports Rec.2020 and YV12, YV16, YV24, YV411, and Y8.

The function for setting the default can still be found near the end of the script, and now looks like this.
function CR_ColorCorrect() { return 0 }
So you can enable either conversion method as the default and use ColorCorrect=0 to disable it, or leave it disabled by default and use ColorCorrect=1 (or 2) as required. I've updated the help file

Feel free to check my work. I'm new to converting with DitherTools. The color conversion section is about halfway down the script.

hello_hello
9th August 2019, 09:03
Damn!

Sorry folks, I just noticed a silly in the definition of SD, HD and UHD resolutions for color conversion. I used "or" when I should have used "and" and "and" when I should have used "or". I'll fix it shorty and update link in the opening post and change the version date to 2019-08-10.

wonkey_monkey
9th August 2019, 11:08
"and" and "and"

Buffalo buffalo buffalo Buffalo buffalo Buffalo buffalo buffalo.

hello_hello
9th August 2019, 11:27
The opening post is updated again now. I didn't change the version date again as the link was only active for a few minutes before I pulled it to upload a version that also checks for bitdepth when using Avisynth+, as currently only 8 bit video is supported for automatic color correction. Now I remember why I removed it originally. :)

I don't actually know how to color convert video with bitdepths greater than 8 bit, but I've come this far....
What's used for color conversion these days (I won't bother with stacked 16 bit, but for native Avisynth+ bitdepths > 8)?

Maybe I should also add an argument for specifying an output bitdepth?

Cheers.

hello_hello
9th August 2019, 12:44
Buffalo buffalo buffalo Buffalo buffalo Buffalo buffalo buffalo.

I had to google that one. I hadn't come across it before. Interesting.... :)

FranceBB
9th August 2019, 15:42
FranceBB,
as it turns out, you talked me into it. Color conversion has been added back to the "official" version. It's now dated 2019-08-09. I'll update the link in the opening post shortly.

I've added back the ColorCorrect argument, but rather than true or false, 0 is disabled, 1 converts with ColorMatrix.dll, and 2 converts with DitherTools. Conversion between SD, HD and UHD colorimetry is now supported.
I don't think there's a 64 bit version of ColorMatrix with Rec.2020 support, but the included 32 bit version has it. It supports YV12 & YUY2.
DitherTools supports Rec.2020 and YV12, YV16, YV24, YV411, and Y8.

The function for setting the default can still be found near the end of the script, and now looks like this.
function CR_ColorCorrect() { return 0 }
So you can enable either conversion method as the default and use ColorCorrect=0 to disable it, or leave it disabled by default and use ColorCorrect=1 (or 2) as required. I've updated the help file

Feel free to check my work. I'm new to converting with DitherTools. The color conversion section is about halfway down the script.

Wow, that's great!


I don't actually know how to color convert video with bitdepths greater than 8 bit, but I've come this far....
What's used for color conversion these days (I won't bother with stacked 16 bit, but for native Avisynth+ bitdepths > 8)?

Maybe I should also add an argument for specifying an output bitdepth?

Cheers.


In the normal Avisynth, 16bit stacked and interleaved are used; since you are using Dither Tools, you may wanna use 16bit stacked as it's easier to implement giving the way you are doing it for 8bit already. Anyway, if you wanna check for Avisynth+ high bit depth, in order to go from BT2020 SDR to BT709 SDR and vice versa I personally use HDRTools by JPSDR, which supports native high bit depth (10/12/14/16 bit planar). Anyway, that's not gonna work for folks who use regular Avisynth.

hello_hello
9th August 2019, 17:23
In the normal Avisynth, 16bit stacked and interleaved are used; since you are using Dither Tools, you may wanna use 16bit stacked as it's easier to implement giving the way you are doing it for 8bit already. Anyway, if you wanna check for Avisynth+ high bit depth, in order to go from BT2020 SDR to BT709 SDR and vice versa I personally use HDRTools by JPSDR, which supports native high bit depth (10/12/14/16 bit planar). Anyway, that's not gonna work for folks who use regular Avisynth.

The problem with a stacked 16 bit input is it doubles the height of the video, which means I'd probably need to rework a lot of the script so an LSB input can be specified and it can still calculate the correct cropping and resizing and pass the info to DitherTools.
There's an included resizing wrapper function (CR_Resize16X) that uses the ResizeX script and DitherTools to resize in 16 bit, and it can be configured to output a stacked 16 bit clip, but even that would throw a spanner in the works as the script decides whether to add borders and color correct after resizing, and it'd probably calculate the wrong DAR for MeGUI even though it'd still crop and resize correctly. Given stacked 16 bit is a legacy format, I'm not sure it's worth accommodating.

I looked at avsresize, but the order in which the script does things would probably require a bit of adjusting because it'd be silly to not have it do both the resizing and color conversion. Plus it appears not to run on XP (I assume that's the problem).

I'll check out HDR Tools at some stage though, when I'm not bored with looking at the script. If it'll simply color convert any native Avisynth+ bitdepth as ColorMatrix does for 8 bit, then I can probably add the color conversion without having to worry about the input/output bitdepth as such.
Assuming it runs on XP? If not, I'll have to modify the script and ask you to test it for me. ;)

PS And what about HDR video? Should I think about that or is it impossible to have the script handle it automatically (in respect to color correction)?

FranceBB
10th August 2019, 15:04
Right, 16bit stacked or interleaved output MSB and LSB stacked or interleaved one with the other, so it would screw up the calculation made by the script as the resolution would be wrong. As to HDRTools by JPSDR, I can tell you that it works absolutely fine on Windows XP, however it might require a lot of RAM for UHD sources and BT2020 to be processed with 16bit precision and that's an issue for 32bit systems 'cause it would have to be split using MPPipeline in order to avoid to hit the maximum memory available per single process. Anyway, as to HDR, that's not an easy task, as you are no longer dealing with resolutions and color matrices, but with color curves. Hence, there isn't a perfect mathematical formula to go from a curve to another and the way you would be bringing something to something else would be according to what looks best for you and once you have done it, there's no way to go back. What I mean by this is that you should think about PQ, HLG and BT709 linear as curves and in order to go from a curve to another you need a function that takes some values in input and outputs some other values... however, from our Calculus class we know that functions can be 1 to 1 or onto and if they are both 1 to 1 and onto then they are bijective. Viewing this in a linear algebra setting means that the matrix of linear transformation associated with our function is an isomorphism which basically means that we can go back and forth between the input and the output losslessly 'cause we can invert them, but when you are dealing with PQ, HLG and BT709 linear, there's no way to have an isomorphism and to go back to where you started losslessly.
I've been talking about this more in depth in my "FranceBB LUT Collection" as I thought that it was an interesting topic for linear algebra lovers and because companies were selling matrices of linear transformation for 200 bucks each while I really wanted to make mine open source and offer them for free.

Anyway, back to our original topic, I think that using HDRTools to deal with UHD would require a not so hard modification to the code as you can see the command for the conversion between BT2020 SDR and BT709 SDR in the very first page of Jean Philippe's topic. As to HDR, I would be very reluctant about including it 'cause:

- There's no way to know whether an HDR source is HDR except for the metadata that you would have to check from the indexer if the indexer does pass them, as Avisynth doesn't know anything about color curves.

- even if you manage to get the information from the indexer 'cause it passes it, there's no way to be 100% sure that whoever encoded the file actually included the right metadata. I've seen far too many files wrongly flagged by either Studios or NLE, or cameras.

- it's not just PQ and HLG, there are many other color curves like C-log, log-C, Slog1, Slog2, Slog3, F-log, D-log...

- There isn't a clear mathematical connection between curves and the function that it's used to go from one to another and you will always have to make sure that the conversion is both mathematically correct and it looks good according to your taste which the user might not like (linear transformation, tonemapping algorithms like Hable, Möbius and Reinhard etc).

For all these reasons, I would not include HDR conversion in the script. Trust me, it's a far too big subject that still makes us (broadcast encoder) think...

hello_hello
11th August 2019, 19:26
FranceBB,
Thanks for all the info! There's a couple of things that I don't quite understand though. The HDR Tools docs say:
"If you want a true correct precise/perfect conversion, I would advise you to use a resampler and feed directly to YV24."
Does "resampler" mean something other that the built in Avisynth Convert function?

Also, there's two types of Rec.601. Color=3 (BT601_525) and Color=4 (BT601_625). My understanding is the PAL and NTSC colorimetry is the same in digital-land, so I don't understand the distinction here when everyone else only refers to a single flavour of Rec.601.

I experimented a little and it's doing my head in.
My Source is rec.709 and I'm downscaling it. Converting between rec.709 and rec.601 seems consistent for each method, aside from HDR Tools causing some banding above the guy's head on the right. You might have to run it full screen to see it.

A ConvertYUVtoXYZ(Color=2).ConvertXYZtoYUV(Color=3, pColor=2, OutputMode=2)
https://i.postimg.cc/Cd81fMWP/A.png (https://postimg.cc/Cd81fMWP)
B Dither_convert_yuv_to_rgb(matrix="709", slice=false).Dither_convert_rgb_to_yuv(matrix="601", output="YV12")
https://i.postimg.cc/GBNLH6zn/B.png (https://postimg.cc/GBNLH6zn)
C ColorMatrix(mode="Rec.709->Rec.601", clamp=0)
https://i.postimg.cc/N5w08qtg/C.png (https://postimg.cc/N5w08qtg)

Keep in mind these are all being converted to RGB using rec.601 on playback, but I don't think that should prevent the result being the same each time.
DitherTools and ColorMatrix agree on rec.709 <-> rec.2020 conversions but HDR Toiols doesn't. I copied the syntax from the help file.

D ConvertYUVtoXYZ().ConvertXYZtoYUV(Color=1, pColor=2, OutputMode=2)
https://i.postimg.cc/2bZzvTXb/D.png (https://postimg.cc/2bZzvTXb)
E Dither_convert_yuv_to_rgb(matrix="709", slice=false).Dither_convert_rgb_to_yuv(matrix="2020", output="YV12")
https://i.postimg.cc/qg2Jvb3W/E.png (https://postimg.cc/qg2Jvb3W)
F ColorMatrix(mode="Rec.709->Rec.2020", clamp=0)
https://i.postimg.cc/K10vy1Mz/F.png (https://postimg.cc/K10vy1Mz)

DitherTools and ColorMatrix don't agree on rec.601 <-> rec.2020 conversions, and I still couldn't get anything sensible out of HDR Tools.

G ConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=3, pColor=1, OutputMode=2)
https://i.postimg.cc/jn6t32TR/G.png (https://postimg.cc/jn6t32TR)
H Dither_convert_yuv_to_rgb(matrix="2020", slice=false).Dither_convert_rgb_to_yuv(matrix="601", output="YV12")
https://i.postimg.cc/sB1ff3YJ/H.png (https://postimg.cc/sB1ff3YJ)
I ColorMatrix(mode="Rec.2020->Rec.601", clamp=0)
https://i.postimg.cc/bD7wF429/I.png (https://postimg.cc/bD7wF429)

All the above was done with classic Avisynth on XP, but a quick look indicated it's the same for Avisynth+.

By the way, I may have missed it, but what does the XYZ in ConvertXYZtoYUV etc actually stand for?

Cheers.

hello_hello
12th August 2019, 16:10
I was hoping I'd uploaded the last version, aside from sorting out the color correction, but a bug managed to slip past the keeper.

Fixed an incorrect output display aspect ratio calculation when NoResize=true and an input sample aspect ratio was specified. The script was still cropping correctly, but the output display aspect ratio calculation was wrong.

New version in the opening post dated 2019-08-12.

FranceBB
13th August 2019, 17:49
what does the XYZ in ConvertXYZtoYUV etc actually stand for?

The XYZ colorspace rather than YUV.
This is because HDRTools allows you to do the conversion in either RGB or XYZ and then it allows you to convert back to YUV.
In the screenshot you posted about BT2020 SDR, I would trust HDRTools as it's normal that colors look off if you view it with a player and a display that don't know anything about BT2020.
For instance, this is sample in BT709 yv12 8bit planar:

https://i.imgur.com/ZdTGLHQ.png

This is the conversion to BT2020 XYZ:

https://i.imgur.com/G8lSDoC.png

And this is the final output of the BT2020 yv24:

https://i.imgur.com/pgiJOJ9.png

This is another example:

BT709 yv12:

https://i.imgur.com/XCJMYCf.png

BT2020 XYZ:

https://i.imgur.com/qXqX19Y.png

BT2020 YUV:

https://i.imgur.com/m27dlef.png


Of course if you playback the file on a good player, let's say MPV, and on a screen that's capable of representing the BT2020 SDR colorspace, then you're gonna see colors in the right way.
Even if you use MPV on a BT709 only capable display, you're very likely gonna see the right colors as MPV is gonna convert it back to BT709 SDR by inverting the process and re-mapping the BT2020 into BT709.


This is the ATP Masters 1000 Montreal, Canada, which is currently on air on Sky Sports:

BT709 yv12:

https://i.imgur.com/zcvNlPp.png

BT2020 XYZ:

https://i.imgur.com/8y0qUI5.png

BT2020 yv24:

https://i.imgur.com/rESwLRk.png

This is simply done by using:

ConvertYUVtoXYZ()
ConvertXYZtoYUV(Color=1,pColor=2)


Does "resampler" mean something other that the built in Avisynth Convert function?


I think so, 'cause the more precision you have, the better. Anyway, since you said that this is all done in normal Avisynth, I think that HDRTools is using 8bit precision and that's why you're seeing banding.
I gotta be fair, though, I've never used HDRTools for BT601 to BT2020 conversion, but only for BT709 SDR to BT2020 SDR and vice-versa and I gotta say that I'm pretty sure that it's doing a good job in that, but I have no idea about how it's handling BT601. I've also been using it to apply tone-mapping to my source to go from HDR PQ and HLG to BT709 and I tried the three tone-mapping algorithms and I found out that Reinhard was the best one (I made a long post about the comparison), anyway, once again, I've never used it for BT601 to BT2020 conversion, however these differences are unexpected. I mean, I expected similar results when going from a color matrix to another... There must be something wrong, but I don't know what.

hello_hello
14th August 2019, 17:49
Thanks for the info again FranceBB!

So XYZ is an actual colorspace? I'll have to research it.

I'll probably take some more screenshots and start a new thread rather than bog this one down with the color conversion stuff. I still think the result should be the same each time, even if the Avisynth output is always being converted to RGB by MPC-HC with rec.601 when viewing it. Even if it looks completely wrong, I'd have assumed the wrongness should be the same no matter which program is doing the conversion.

Thanks again.

FranceBB
14th August 2019, 18:44
So XYZ is an actual colorspace? I'll have to research it.


Sure! :) Link (https://en.wikipedia.org/wiki/CIE_1931_color_space)
Too bad that it isn't actually officially supported by Avisynth+ 'cause it's used in Digital Cinema; for instance, I was trying to convert things to it a few days ago when I was trying to encode a DCP (https://forum.doom9.org/showthread.php?t=176702) (Digital Cinema Package) encoded in Motion JPEG 2000 XYZ.

Even if it looks completely wrong, I'd have assumed the wrongness should be the same no matter which program is doing the conversion.

Well, yes, that's what I expected as well, which is why I don't understand what's going on and why we're getting those very different results.

ChaosKing
14th August 2019, 19:30
Sure! :) Link (https://en.wikipedia.org/wiki/CIE_1931_color_space)
Too bad that it isn't actually officially supported by Avisynth+ 'cause it's used in Digital Cinema; for instance, I was trying to convert things to it a few days ago when I was trying to encode a DCP (https://forum.doom9.org/showthread.php?t=176702) (Digital Cinema Package) encoded in Motion JPEG 2000 XYZ.


I'm not sure if it helps, but I saw that vapoursynth mentions XYZ in "resize" (use strg+f ;-)
http://www.vapoursynth.com/doc/functions/resize.html

p.s you can easily use avisynth stuff in VS with avsproxy

FranceBB
14th August 2019, 19:41
I'm not sure if it helps, but I saw that vapoursynth mentions XYZ in "resize" (use strg+f ;-)
http://www.vapoursynth.com/doc/functions/resize.html

p.s you can easily use avisynth stuff in VS with avsproxy

Wow! Hold on a second, you're telling me that not only VapourSynth supports XYZ, but it also supports a lot of other interesting things like log! I really hope that Ferenc will port them to Avisynth+ when he has time, not that he has much time, giving the million other things he is planning to do for Avisynth+.

hello_hello
14th August 2019, 20:33
I haven't looked hard but I can't see what strg+f refers to yet. :(

I've done some more testing and I'll start a new thread later, but converting in one direction only, here's the highlights. At the moment I'm tempted to say DitherTools would be getting it right, but I don't know for sure.
HDRTools "Linear" refers to this sort of thing: ConvertYUVtoLinearRGB().ConvertLinearRGBtoYUV()

Rec.709 To Rec.601
All conversion methods agree. HDR Linear looks better than HDR XYZ (no banding).

Rec.2020 To Rec.601.
DitherTools and HDR Linear agree.
ColorMatrix different, HDR XYZ seems borked.

Rec.2020 To 709.
I'd only be guessing as nobody agrees.
DitherTools and HDR Linear possibly only disagree for "red".
I think ColorMatrix is wrong.
I think HDR XYX is even wrongerer. :)

I should upload the images shortly and start the new thread before I lose interest again....

Edit: A bit of a delay. I just realised I was using DitherTools 1.27.1. I'll redo the DitherTools conversions with 1.27.2 before starting the new thread in case that changes things. Damn...

Edit: The two versions of DitherTools are identical.

Edit: Here's the new thread. https://forum.doom9.org/showthread.php?p=1881952#post1881952

ChaosKing
14th August 2019, 22:16
I haven't looked hard but I can't see what strg+f refers to yet. :(


I meant use STRG+F (=Browser search function) to search for xyz on the website :D

pinterf
15th August 2019, 08:41
Wow! Hold on a second, you're telling me that not only VapourSynth supports XYZ, but it also supports a lot of other interesting things like log! I really hope that Ferenc will port them to Avisynth+ when he has time, not that he has much time, giving the million other things he is planning to do for Avisynth+.
z_ConvertFormat
https://forum.doom9.org/showthread.php?t=173986
"See VapourSynth documentation for valid string constants."

hello_hello
15th August 2019, 10:56
I meant use STRG+F (=Browser search function) to search for xyz on the website :D

Ahhhh.... You mean Ctrl+F? :)
That only opens a page search for my browser.

ChaosKing
15th August 2019, 11:13
Ahhhh.... You mean Ctrl+F? :)
That only opens a page search for my browser.

omg german (keyboard) brain xD

strg = ctrl

hello_hello
15th August 2019, 13:35
omg german (keyboard) brain xD

strg = ctrl

Yeah, I did a google search for that one. :)

hello_hello
16th August 2019, 18:38
There's an updated version of CropResize in the opening post, blocking colorMatrix from being involved in Rec.2020 conversions. DitherTools can be used instead. I still have plans to add high bitdepth color correction at some stage, but in the mean time.....

The new version is dated 2019-08-17.

hello_hello
3rd September 2019, 04:34
There's an updated version of CropResize in the opening post, dated 2019-09-02. With any luck that'll be it for quite a while, as the script's color correction (converting the colorimetry when upscaling/downscaling) was the only thing left to sort.

Under "ColorCorrect" in the help file, there's a mini essay on my current understanding of color conversion, when to convert and how to do it.
There's now four conversion choices.

1. ColorMatrix
2. DitherTools
3. HDRTools (170m for SD)
4. HDRTools (470bg for SD)

DitherTools can no longer be used for Rec.2020 conversions, but if it's converting the colors, DitherTools will do the resizing too (when a compatible resizer is specified). Only standard dynamic range is supported. I don't think HDR to SDR conversions can be done automatically, I've almost no experience with HDR, and I've no interest in HDR anyway.

Some other changes -

- Avisynth 2.5.8 is no longer supported. As it turns out, the script was already using a couple of functions not available in Avisynth 2.5.8.

- Added a PicDim argument for adjusting how much the picture is dimmed when Info=true. The default is -75. The range is -255 to 0.

- Tweaked Info=true. The displayed info scales a little better with resolution. The source color format and bitdepth are now displayed.
I also noticed an Avisynth+ oddity that causes negative zero (such as a right or bottom cropping of zero) to be displayed with the negative sign under some circumstances. I added a workaround to prevent zero from displaying as a negative, because it was annoying me.

For anyone interested, Avisynth+ displays this as 0
zz = float(-0)
subtitle(string(zz))

but displays this as -0
zz = float(0)
subtitle(string(-zz))

Avisynth 2.6 doesn't display the negative sign either way.

In case I did a stupid, there's still a link for the 2019-08-17 version in the opening post, but the new version should be fine.

hello_hello
10th September 2019, 12:46
This isn't an update to the script itself, as it's exactly the same as the version dated 2019-09-02, but I've update the help file a little. There's no longer any optional plugins included with the script, but there's still links for them at the top of the help file. Including plugins in the zip file was only supposed to be a temporary thing as they'll become outdated.

Even though the script itself is unchanged, I've updated the version to 2019-09-10. There's a new link in the opening post.

hello_hello
20th September 2019, 04:28
I assume nobody is using the global GCropResize function, given nobody's complained about it not working and the last version broke it.

Changes 2019-09-20:
- Fiddled with Info=true again. The Avisynth and CropResize versions are now displayed.
For an anamorphic source and/or output, the source and/or output "display dimensions" are included (right column). The height is the source/output height. The width is the source/output width, as it would be when resized to "square pixel" dimensions on playback. If necessary, "display width" is rounded to an integer (a whole pixel).
- Avisynth Neo probably didn't work correctly with CropResize. Added a check for Neo, although the script doesn't do anything "Neo specific". It now assumes Avisynth+ is being used when Neo is detected.
- The GCropResize function was completely broken after the last update. If GCropResize was used an error message displayed (due to a typo).

hello_hello
20th September 2019, 10:12
If anyone has downloaded the 2019-09-20 version before reading this, or before the 21st, please download it again. I haven't change the version date but I somehow broke Info=true, despite being positive I checked it before uploading the script. Sigh....

hello_hello
7th January 2020, 15:56
I've uploaded a new version of CropResize dated 2020-01-07. There's a link in the opening post along with a summary of changes since the previous version.

I've also updated the pictures illustrating CropResize usage in the second post.

redbtn
7th January 2020, 19:06
Do you have any plans to release Vapoursynth version?

hello_hello
7th January 2020, 20:41
redbtn,
I know nothing about Vapoursynth. I have an old machine running Win7 now (previously only XP), so I have plans to install Vapoursynth and learn to use it, but knowing enough to create a native Vapoursynth version is a "maybe sometime later this year" thing at best.

I do recall bumping into a post a while back where someone had an old version of CropResize working in Vapoursynth...
Here it is.... https://forum.doom9.org/showthread.php?p=1830238#post1830238
Is the avsproxy (https://forum.doom9.org/showthread.php?t=175141) plugin a way to use CropResize? Or vsavsreader (https://forum.doom9.org/showthread.php?t=165957)?

I ask, as I have no idea.

redbtn
8th January 2020, 00:34
@hello_hello thank you for reply! I have no experience to run AVS Plugins in VS, but I'll try.

hello_hello
25th January 2020, 14:15
Another update for CropResize, simply to add a "Position" argument for displaying the current frame number and position in time over the video. Sometimes it's handy and it saves having to use a separate function.
Enabling it requires GRunT. http://avisynth.nl/index.php/GRunT

The new version is dated 2020-01-25, and as usual, there's a link in the opening post.

hello_hello
30th January 2020, 03:20
Sorry folks, but another update. I discovered I'd added a line to the script for testing the color conversion and forgot to remove it, causing the script to throw an error for sources with a bitdepth greater than 8 when color converting with HDRTools. The new version is dated 2020-01-30 and the link is in the opening post.

hello_hello
26th March 2020, 07:41
There's a link for an updated version of CropResize in the opening post, containing some minor fixes. The new version is dated 2020-03-26. There's a text file included describing the changes.

hello_hello
22nd June 2020, 20:16
There's a link for an updated version of CropResize in the opening post, containing fixes for a couple of obscure aspect ratio bugs when specifying an Output DAR. The new version is dated 2020-06-23.

Another link:
CropResize 2020-06-23.zip (https://files.videohelp.com/u/210984/CropResize%202020-06-23.zip)

hello_hello
12th September 2020, 05:43
There's a link for an updated CropResize in the opening post dated 2020-09-11. There's a summary of changes above the link.

hello_hello
28th October 2020, 17:07
There's a link for an updated CropResize in the opening post dated 2020-10-28. It fixes a minor color conversion gremlin. Details in the "Changes" text file.

hello_hello
30th October 2020, 04:52
Sorry about an update so soon. It was just to fix some obsolete information in the help file, but I changed the version date to 2020-10-30.
There be a link in the opening post.

hello_hello
5th November 2020, 11:28
Mainly a little more fiddling with the color correction. New version dated 2020-11-05.

Danette
24th December 2020, 00:49
Edit: Sorry about the essay, but hopefully this will help makes things clearer. :)

The script simply uses the supplied InDAR to base the calculations on. If no InDAR/InSAR is specified, it assumes the source is non anamorphic (square pixels). If you were to do the following, it wouldn't crop at all as the InDAR and output DAR (resolution) are the same. Info=true will show you what it's doing.
CropResize(640,480, 0,0,0,0, InDAR=4.0/3.0, Info=true)
For the following it barely crops as the output dimensions almost match the InDAR.
CropResize(652,480, 0,0,0,0, InDAR=15.0/11.0, Info=true)
For the next example, the shape of objects in the picture will be exactly the same after resizing as for the previous one, but because the output width is narrower this time, it has to crop the sides.
CropResize(640,480, 0,0,0,0, InDAR=15.0/11.0, Info=true)
So it's not agreeing about the AR, or auto-cropping in the traditional sense, it's just preventing an aspect error based on the InDAR and output dimensions. It just happens that InDAR=15.0/11.0 requires 16 pixels to be cropped from the width if you want a 4:3 output. If you want to use that InDAR (which I think we decided is correct), but don't want to crop, you can increase the output width a bit.

Think of any specified cropping as the minimum cropping, but the script will increase it as required to prevent aspect error. To see what's being cropped, enable a cropping preview. The yellow lines are the specified cropping and any blue lines are the additional script cropping. The video isn't resized while the cropping preview is enabled.
CropResize(640,480, 10,4,-6,-4, InDAR=15.0/11.0, CPreview=1, Info=true)

For a 16:9 DVD the equivalent InDARs are (and specifying 16:9 output dimensions for resizing).
CropResize(768,432, 0,0,0,0, InDAR=16.0/9.0) - generic DAR
CropResize(768,432, 0,0,0,0, InDAR=20.0/11.0) - mpeg4 DAR

The main idea of CropResize is to crop and resize without having to calculate aspect error and adjust the cropping or resizing manually to prevent it. An example might be cropping a 1080p source and resizing to 720p. If you don't specify a height (use zero instead), the script will apply your cropping and then pick the appropriate height for you. Because it's free to pick the height, any additional cropping to prevent aspect error will be fairly minimal. You can do exactly the same thing with a DVD source as long as you use the correct InDAR
(cropping a 1080p source like this would mean you have a video with a 2.40:1 aspect ratio after cropping the black).
CropResize(1280,0, 4,140,-2,-142)
If you were to specify the same cropping as above with 4:3 output dimensions (still a 1080p source), it'd apply the specified cropping, then crop a huge amount from each side to give you a 4:3 output without distorting the picture.
CropResize(720,540, 4,140,-2,-142)

I find it very handy when working with video where the amount of black varies quite a bit (usually old DVDs), but I'm OCD about cropping it all. So I can do something like the following, specifying enough cropping to remove the black, without having to worry about distorting the picture, because CropResize won't let me.

Trim(0,1596).CropResize(640,480, 8,0,-8,0, InDAR=15.0/11.0) ++ \
Trim(1597,1884).CropResize(640,480, 16,2,-8,-4, InDAR=15.0/11.0) ++ \
Trim(1885,2597).CropResize(640,480, 24,4,-12,-2, InDAR=15.0/11.0) ++ \
Trim(2598,0).CropResize(640,480, 8,0,-8,0, InDAR=15.0/11.0)

But anyway... what I was trying to explain in my previous post, is if you were to decide the source is 4:3 after you only crop 14 pixels from the sides, you can do it by specifying the appropriate InDAR, and that's the DAR the script will base it's calculations on. Use Info=true and you'll see it's only cropping 7 pixels each side here instead of 8.
CropResize(640,480, InDAR=1.35977, Info=true)

CropResize does have a "traditional" auto-cropping option. It requires the AutoCrop plugin (autocrop.dll). When it's enabled, the source is auto-cropped with autocrop.dll, any specified cropping is applied to the auto-cropped video, if necessary the script applies additional cropping to prevent aspect error, then it resizes. Try the following. Assuming auto-crop crops some or all of the black from the sides, the script will then crop 8 more pixels each side, and to prevent aspect error it'll crop a few pixels top and bottom before resizing to 4:3 dimensions.
CropResize(640,480, 8,0,-8,0, AutoC=true, InDAR=15.0/11.0, Info=true)
If you don't specify a height, you probably won't end up with a 4:3 output, but at the same time the script probably won't have to crop much extra picture to prevent aspect error.
CropResize(640,0, 8,0,-8,0, AutoC=true, InDAR=15.0/11.0, Info=true)

Thought it best to move this discussion here, since we are now focusing on this interesting ”CropResize” creation.

I’m trying to digest all of this and, after reading the above from the “Moire Effect & TFM(pp=0) Solution” thread and your initial post in this thread, I may be getting closer to understanding what this does and how I might prefer to use it.

As you may recall, I would accept borders, and even some edge video degradation, in order to retain as much content as possible. I think I’m becoming more interested in using the AutoCrop function in combination with cropping width only, as shown in one of your examples. So, trying to put it all together, I’ve come up with this as a way to meet my goals:

iCropResize(640,480,AutoC=true,InDAR=15.0/11.0,ResizeWO=true,Info=true)

Does it make sense? Would using CleanBorders=true, instead of ResizeWO=true, also crop width only? Is there any advantage to using one vs. the other?

After setting this for a an entire TV series, I suppose that I’ll have to try to find those one or two known circles/spheres and./or squares to verify correct AR as well as keeping an eye on those left and right crops to make sure I’m ok with what is going on there.

hello_hello
24th December 2020, 14:28
Here's another essay for you. :)
For anyone else reading this post, we're talking about how to crop and resize a 4:3 NTSC DVD here, but specifying an mpeg4 DAR of 15:11 (1.36364) for the DVD instead of 4:3 (1.33333).

For the explanation of the different modes, I'll ignore auto-cropping for the moment. You're probably aware how anamorphic encoding works, so sorry if the "NoResize mode" explanation is stating the obvious.

When resizing is disabled completely (NoResize=true), the script only crops. So for an anamorphic source you need to set the correct sample aspect ratio when encoding, which would be -sar 10:11 in the encoder command line in this case. The sample aspect ratio isn't changed by cropping (only by resizing), so you can crop, set the SAR for the encoder, and the player will resize the encoded video to the correct aspect ratio on playback, just as it does for the DVD. The CropResize output dimensions are completely ignored when resizing is disabled (unless adding borders is enabled), so they might as well be zero.

CropResize(0,0, 8,0,-8,0, InDAR=15.0/11.0, NoResize=true) # Set -sar 10:11 for the encoder. The output will be 704x480.
The above is exactly the same as simply cropping, but for CropResize, Info=true will tell you the correct SAR to use for encoding, based on the specified DAR.
Crop(8,0,-8,0)
Reduce the cropping each side if 8 pixels crops picture, or don't crop at all, set -sar 10:11 for the encoder, and let the player resize the encoded video (if you specify InDAR=4.0/3.0, Info=true will tell you 8:9 is the SAR, and if don't crop, it would show the video would be resized to exactly 4:3 on playback).

CleanBorders also disables resizing, as it's purpose is only to replace the existing borders with clean ones. If the amount of cropping is uneven, CleanBorders centres the picture. The output dimensions are always the same as the source dimensions, so they might as well be zero. Whatever you crop/auto-crop is replaced with black borders.
CropResize(0,0, 8,2,-8,-2, InDAR=15.0/11.0, CleanBorders=true) # Set -sar 10:11 for the encoder and the output will be always be 720x480 with a 15:11 DAR.

Resize Width Only mode defaults to resizing to square pixel dimensions, and both the output width and height are ignored (unless you set an OutDAR or enable adding borders), so once again they might as well be zero.
CropResize(0,0, 8,0,-8,0, InDAR=15.0/11.0, ResizeWO=true) # Based on the specified cropping and InDAR, the output will be 640x480.
The following would output 640x476.
CropResize(0,0, 8,2,-8,2, InDAR=15.0/11.0, ResizeWO=true)
If you cropped a little more from the sides, you'd end up with 636x476.
CropResize(0,0, 10,2,-10,2, InDAR=15.0/11.0, ResizeWO=true)

As far as auto-cropping goes, you don't know how much it'll crop from the sides if the amount of black varies, or if there's sometimes black top or bottom, so as per the above examples, there's no guarantee the output dimensions will be the same every time for either ResizeWO or NoResize, whereas full resizing mode can do whatever it likes to always output the specified dimensions.
Although keep in mind ResizeWO might still have to crop an extra pixel or three after auto-cropping so it can resize the width without distorting the picture. That's partly because by default, both ResizeWO and NoResize output mod4 dimensions (width and height both evenly divisible by 4). I don't necessarily recommend it, but you can change that to mod2 so ResizeWO has a little more freedom when resizing the width, and therefore any extra cropping would be quite minimal. For NoResize mode, mod2 means it'll never crop more than was cropped by auto-crop, unless you specify manual cropping too.
CropResize(0,0, AutoC=true, InDAR=15.0/11.0, Mod=2, ResizeWO=true)

So there's no perfect answer if you auto-crop. It depends if you want the same output dimensions each time. As you'd rather not crop picture, if you're happy to keep a little of the black, I'd consider forgetting about auto-cropping and resize to square pixel dimensions this way:
CropResize(0,0, 3,0,-3,0, InDAR=15.0/11.0, ResizeWO=true)
Or in this case, the following does exactly the same thing:
CropResize(648,480, 3,0,-3,0, InDAR=15.0/11.0)
The total cropping each side will always be 3.6 pixels, it'll probably never be enough to crop picture (even if it doesn't crop all the black), the height will never be cropped or resized, and the output will always be 648x480.

Hopefully that made things a little easier to understand rather than more confusing. :)

bruno321
29th December 2020, 07:15
Thanks for this, I've been using it really often, only for resizing according to SAR or DAR though, no cropping.

Something I noticed is: if I use CropResize(InSAR=8.0/9.0) to emulate a generic NTSC "4:3" situation, it resizes from 720x480 to 640x480. I'd prefer it resized it to 720x540 -- upsizing, not downsizing, as happens when playing back a DVD encode with 8:9 SAR. Why does CropResize downsize in this case, and can I make it always upsize instead?

hello_hello
29th December 2020, 23:47
It only does that for 4:3 NTSC DVDs, as the default output dimensions are the source height (after any cropping), and the width resized to square pixel dimensions (after any cropping). Without increasing the height, 4:3 NTSC DVDs are the only DVDs that require the width to be resized down.

You can specify any 4:3 output dimensions you like though.
CropResize(720,540, InSAR=8.0/9.0)
CropResize(624,468, InSAR=8.0/9.0)

Keep in mind if the output dimensions (for square pixel resizing) don't match the source display aspect ratio, the script will crop whatever is required to prevent aspect error, so if in doubt only specify a width, or only the height, and the script will choose the appropriate height or width for you.
CropResize(720,0, InSAR=8.0/9.0)
CropResize(0,540, InSAR=8.0/9.0)

It's a good idea to resize that way if there's a fair bit of black to be cropped and you don't know what the output dimensions should be. For example, if you cropped a 16:9 NTSC DVD like this, you could pick the width (I chose 868 for no particular reason) and the script would take care of the height based on the InSAR or InDAR.

CropResize(868,0, 2,42,-2,-42, InSAR=32.0/27.0) # the output would be 868x404

One other thing to keep in mind, if you were to crop before resizing with CropResize, you'd have to specify the sample/pixel aspect ratio, not the original display aspect ratio, as cropping changes the display aspect ratio. For an NTSC 16:9 DVD, this would produce exactly the same result as above.

Crop(2,42,-2,-42)
CropResize(868, InSAR=32.0/27.0)

Whereas this would resize incorrectly.
Crop(2,42,-2,-42)
CropResize(868, InDAR=16.0/9.0)

For non-anamorphic sources it doesn't matter, because there's no InSAR/InDAR required.

bruno321
30th December 2020, 07:16
Hmm, I guess the advantage of CropResize for me is precisely that I can quickly preview how the final encode is going to look, without having to do the math manually each time. But I'm not seeing how to do that here, given that I typically like to CropResize after manually cropping the black bars out. If I cropped on both height and width, then how can I input to CropResize a SAR of 8/9 and have it give me an upsized result, without manually specifying to it what width or height I wish it to have (like you did with the 868 above)?

If that doesn't exist, perhaps an extra option "Upsize=true" that would always prevent downsizing would be called for? I'd be grateful for it :)