Log in

View Full Version : Automatically Resize a Video


EHarlen
27th April 2026, 16:32
Is it possible to automatically resize a video at a resolution below 1080p to 1080p video using AviSynth while preserving the aspect ratio?

For example; 640x480(4:3) to 1440x1080(4:3) or 1280x720(16:9) to 1920x1080(16:9)

Columbo
28th April 2026, 14:45
It's not clear what you mean by "automatically".

StainlessS
28th April 2026, 16:41
Also, do you want borders cropped, or not.
Bit more info required.
(eg, What is source, eg BlueRay[DGIndexNV], DVD[DGIndex], MP4 file ???, What is dest, Blueray, DVD, etc ???)

EDIT: Some funcs in RT_Stats,


*****************************************************
****** SCRIPT CONVERSION TO PLUGIN FUNCTIONS ********
*****************************************************

Below fns converted from previously existing script functions which will also be supplied so that you can see the logic,
any changes after v1.10 plugin versions may not be reflected in the later script versions.



RT_GetSAR(clip,dar float)
Gets Sample (pixel) Aspect Ratio from DAR Display Aspect Ratio.

***
***
***

RT_GetDAR(clip,sar float)
Gets DAR Display Aspect Ratio from SAR, Sample (pixel) Aspect Ratio.

***
***
***

RT_SignalDAR(float) # See Megui wiki (name change from SetDAR)
Signal DAR to MEGUI. Sets Global vars MeGUI_darX and MeGUI_darY which are read during MEGUI loading of AVS file.

***
***
***

RT_SignalDAR2(int darx,int dary)
As for RT_SignalDAR() except it allows setting of numerator and denominator individually.
Signal DAR to MEGUI. Sets Global vars MeGUI_darX and MeGUI_darY which are read during MEGUI loading of AVS file.

***
***
***

RT_GetCropDAR(clip,float DAR,float "X"=0,float "Y"=0,Float"W"=0,float "H"=0)
Call prior to Crop/Resize with (possibly fractional) cropping to calc resultant DAR, X,Y,W,H are cropping coords
DAR = FAR * SAR ::: FAR = DAR / SAR ::: SAR = DAR / FAR
Cropping affects FAR & usually DAR, resizing does not affect DAR (unless also cropped). Resizing affects FAR and maybe SAR.
We dont allow eg -ve X


Script equivlents,

Function GetCropDAR(clip c,float DAR,float "X",float "Y",float "W",float "H") {
# Call prior to Crop/Resize with (possibly fractional) cropping to calc resultant DAR, X,Y,W,H are cropping coords
# DAR = FAR * SAR ::: FAR = DAR / SAR ::: SAR = DAR / FAR
#
X=Float(Default(X,0.0)) Y=Float(Default(Y,0.0)) W=Float(Default(W,0.0)) H=Float(Default(H,0.0))
W=W<=0.0?c.width+W-X:W H=H<=0.0?c.height+H-Y:H
Assert(X>=0.0&&X < c.width, "GetCropDAR: Invalid X("+String(X)+")")
Assert(Y>=0.0&&Y < c.height,"GetCropDAR: Invalid Y("+String(Y)+")")
Assert(W> 0.0&&X+W<=c.width, "GetCropDAR: Invalid W("+String(W)+")")
Assert(H> 0.0&&Y+H<=c.height,"GetCropDAR: Invalid H("+String(H)+")")
Return c.GetSAR(DAR) * W / H
}

#--------------

# From MeGUI Wiki:
Function GetDAR(clip c, float SAR) { return Float(c.width) * SAR / Float(c.height)} # Gets the DAR from the SAR
Function GetSAR(clip c, float DAR) { return DAR * Float(c.height) / Float(c.width) } # Gets the SAR from the DAR
Function SignalDAR(float DAR){ # Signal DAR for MEGUI (Name change from SetDar)
Assert(DAR>0.0, "SignalDAR: Error, DAR must be greater than zero")
Global MeGUI_darx=Round(1000*DAR) Global MeGUI_dary=1000
}
Function SignalDAR2(int DARX,int DARY){
Assert(DARX>0 && DARY>0, "SignalDAR2: Error, DARX and DARY must be greater than zero")
Global MeGUI_darx=DARX Global MeGUI_dary=DARY
}


The SignalDAR stuff is to signal AR to MeGUI.

SAR = Sample Aspect Ration, ie per pixel.
FAR = Frame Aspect Ratio, ie size in pixels.
DAR = Required display Shape.

When you crop something SAR (Sample, ie pixel size) does not change.

So if known DAR, find the SAR with GetSAR().
Crop and find current DAR via GetDAR().

################################

EDIT:
Here a small part of massive script, it would initially call sub fuction to auto crop, then left to user to manually set crop coords
and comment out the DoSeq() call. This to avoid long timouts in MeGUI as it would call the pre-processing auto crop stuff up to about 7 times.
This script does not try to keep borders at all, meant for final viewing MPG/MP4/MKV only, not for encode to BlueRay or DVD.


SOURCE_CLIP = Last

SOURCE_DAR=16/9.0
SOURCE_SAR=SOURCE_CLIP.RT_GetSAR(SOURCE_DAR)
RT_DebugF("SOURCE_DAR=%f SOURCE_SAR=%f",SOURCE_DAR,SOURCE_SAR)
return Doseq # This is a call to script which auto crops source and shows crop coords which should be user set below.
# Then this line commented out


CROP_X=0 CROP_Y=0 CROP_W=-0 CROP_H=-0

SOURCE_CLIP.crop(CROP_X,CROP_Y,-ABS(CROP_W),-ABS(CROP_H))

Global G_QBC=FALSE # switch off future autocrop

BORDER_CROPPED_DAR=RT_GetDAR(SOURCE_SAR)
RT_DebugF("Border Cropped DAR=%f",BORDER_CROPPED_DAR)


AR_MAX = 2.21 # Maximum Aspect Ratio, Width cropped if greater.
AR_MIN = 0.0 # Minimum Aspect Ratio, Height cropped if Lesser.

############
# Required Output Dimensions control.
# dim = -1 ) As original Dimension after Border & Aspect Ratio Limiting cropping.
# dim = -ve ) Min(original Dimension after Border & Aspect Ratio Limiting cropping, Abs(dim after cropping))
# dim = +ve ) Dimension is set to the explicitly set value that is greater than 0.
# dim = 0 ) This dimension is FAR (Frame Aspect Ratio) resized using the alternate dimension and SAR 1:1 [so is same as original cropped DAR <after border and Aspect ratio Limiting>]
# OUTPUT_W and OUTPUT_H CANNOT BOTH be 0, else Error.
############

OUTPUT_W = 0
OUTPUT_H = -1

###
Assert(OUTPUT_W!=0 || OUTPUT_H!=0,"OUTPUT_W and OUTPUT_H Cannot both be zero")
BORDERCROPPED_CLIP=Last
W=Width H=Height FAR = W/Height.Float

if(FAR*SOURCE_SAR > AR_MAX) { # WIDTH CROPPED to AR_MAX # Cropping does not change SAR
RT_DebugF("WIDTH cropping to AR_MAX")
Sub_W = Round((W - (H * AR_MAX / SOURCE_SAR))/4) * 4
Sub_Lft = Sub_W / 2
Sub_Rgt = Sub_W - Sub_Lft
New_W = W - Sub_Lft - Sub_Rgt
CROP_X = CROP_X+Sub_Lft
CROP_W = -(ABS(CROP_W)+ABS(Sub_Rgt))
CROP_H = -ABS(CROP_H)
RT_DebugF("Aspect Ratio Limit crop(%d,0,%d,0)",Sub_Lft,Sub_Rgt)
Last = SOURCE_CLIP.crop(CROP_X,CROP_Y,CROP_W,CROP_H)
AR_LIMITED_DAR = Last.RT_GetDAR(SOURCE_SAR) # Cropping (usually) affects DAR
RT_DebugF("New DAR=%.3f",AR_LIMITED_DAR)
} Else if(FAR*SOURCE_SAR < AR_MIN) { # HEIGHT CROPPED to AR_MIN # Cropping does not change SAR
RT_DebugF("HEIGHT cropping to AR_MIN")
Sub_H = Round((H - (W / AR_MIN * SOURCE_SAR))/4) * 4
Sub_Top = Sub_H / 2
Sub_Bot = Sub_H - Sub_Top
New_H = H - Sub_Top - Sub_Bot
CROP_Y = CROP_Y+Sub_Top
CROP_H = -(ABS(CROP_H)+ABS(Sub_Bot))
CROP_W = -ABS(CROP_W)
RT_DebugF("Aspect Ratio Limit crop(0,%d,0,%d)",Sub_Top,Sub_Bot)
Last = SOURCE_CLIP.crop(CROP_X,CROP_Y,CROP_W,CROP_H)
AR_LIMITED_DAR = Last.RT_GetDAR(SOURCE_SAR) # Cropping (usually) affects DAR
RT_DebugF("New DAR=%.3f",AR_LIMITED_DAR)
} Else {
RT_DebugF("NO AR CROPPING")
AR_LIMITED_DAR = Last.RT_GetDAR(SOURCE_SAR) # Cropping (usually) affects DAR
}

AR_LIMTED_CLIP=Last


if(OUTPUT_W > 0 && OUTPUT_H > 0) { # Explicit dual dimension resize, DAR same as frame AR
Global G_DISPWID = ((OUTPUT_W / 4.0) * 4).Round
Global G_DISPHIT = ((OUTPUT_H / 4.0) * 4).Round
OUT_S = RT_String("Output Width based on Explicit Width[%d]",OUTPUT_W)
OUT_S = RT_String("%s\nOutput Height based on Explicit Height[%d]",OUT_S,OUTPUT_H)
FAR = G_DISPWID.Float / G_DISPHIT
OUT_SAR = 1.0
}Else {
If(OUTPUT_W == 0) { # 1:1 Resizing Width
Global G_DISPHIT = (OUTPUT_H > 0) ? OUTPUT_H : (OUTPUT_H == -1 ) ? Last.Height : Min(Last.Height,Abs(OUTPUT_H))
Global G_DISPHIT = Round(G_DISPHIT / 4.0) * 4
Global G_DISPWID = Round(G_DISPHIT.Float * AR_LIMITED_DAR / 4.0) * 4
OUT_S = RT_String("Output 1:1 Resizing Width based on %s Height[%d]",(OUTPUT_H > 0)?"Explicit":"AR_MAX",G_DISPHIT)
}Else if(OUTPUT_H==0) { # 1:1 Resizing Height
Global G_DISPWID = (OUTPUT_W > 0) ? OUTPUT_W : (OUTPUT_W == -1) ? Last.Width : Min(Last.Width,Abs(OUTPUT_W))
Global G_DISPWID = Round(G_DISPWID / 4.0) * 4
Global G_DISPHIT = Round(G_DISPWID.Float / AR_LIMITED_DAR / 4.0) * 4
OUT_S = RT_String("Output 1:1 Resizing Height based on %s Width[%d]",(OUTPUT_W > 0)?"Explicit":"AR_MAX",G_DISPWID)
} Else { # Not 1:1 Resize : Both W and H dims set via pre-cropped size or explicit size.
Global G_DISPWID = (OUTPUT_W > 0) ? OUTPUT_W : (OUTPUT_W == -1) ? Last.Width : Min(Last.Width,Abs(OUTPUT_W))
Global G_DISPWID = Round(G_DISPWID / 4.0) * 4
Global G_DISPHIT = (OUTPUT_H > 0) ? OUTPUT_H : (OUTPUT_H == -1 ) ? Last.Height : Min(Last.Height,Abs(OUTPUT_H))
Global G_DISPHIT = Round(G_DISPHIT / 4.0) * 4
OUT_S = RT_String("Output Width based on %s Width[%d]",(OUTPUT_W > 0)?"Explicit":"AR_MAX",G_DISPWID)
OUT_S = RT_String("%s\nOutput Height based on %s Height[%d]",OUT_S,(OUTPUT_H > 0)?"Explicit":"AR_MAX",G_DISPHIT)
}
FAR = G_DISPWID.Float / G_DISPHIT
OUT_SAR = AR_LIMITED_DAR / FAR
}

Global G_ASPECT_DARX=Round(G_DISPWID * OUT_SAR * 1000) Global G_ASPECT_DARY=Round(G_DISPHIT * 1000)

ORG=Last

Doseq

RT_DebugF("Source: Width=%d Height=%d : SAR=%.3f DAR=%.3f",Source_Clip.Width,Source_Clip.Height,SOURCE_SAR,SOURCE_DAR)
RT_DebugF("Border Cropped: Width=%d Height=%d : SAR=%.3f DAR=%.3f",BORDERCROPPED_CLIP.Width,BORDERCROPPED_CLIP.Height,SOURCE_SAR,BORDER_CROPPED_DAR)
RT_DebugF("AR_LIMITED Cropped: Width=%d Height=%d : SAR=%.3f DAR=%.3f",AR_LIMTED_CLIP.Width,AR_LIMTED_CLIP.Height,SOURCE_SAR,AR_LIMITED_DAR)
RT_DebugF("%s",OUT_S)
RT_DebugF("Output: Width=%d Height=%d : SAR=%.3f DAR=%.3f",Width,Height,OUT_SAR,Last.RT_GetDAR(OUT_SAR))


Above for hint only, not a solution for you.
NOTE, I dont like DAR that is really wide, eg 2.5,nasty skinny strip in screen center.
So, I limit(ie crop) my clips to a max DAR of 2.21 (which is enough for nearly all movies without cropping important text).
2.21 Is also DAR of my Samsung phone.

EDIT: Above script uses "SOURCE_DAR=16/9.0", this script is used for Blueray decode, if was 4.0/3.0 AR then I would manually change it to such. (Or use a different DGIndexNV template, which above script is part of).

EDIT: Oh, G_DISPWID, G_DISPHIT, are output resize dimensions.

EDIT: Looks like HelloHello has got you sorted out good. :)

EHarlen
28th April 2026, 16:57
Also, do you want borders cropped, or not.


No, I don't want borders cropped.

(eg, What is source, eg BlueRay[DGIndexNV], DVD[DGIndex], MP4 file ???, What is dest, Blueray, DVD, etc ???)

Any source. But why?

hello_hello
28th April 2026, 17:24
You can do it using the CropResize function. https://forum.doom9.org/showthread.php?t=176667
If the source aspect ratio is less than 16:9, you'd specify the desired height (1080) and let the function calculate the width.
If the source aspect ratio is greater than 16:9, you'd specify the desired width (1920) and let the function calculate the height.
You could automate it with something like this:

Source = last
W = width(Source)
H = height(Source)
Aspect = float(W) / float(H)

if (Aspect < (16.0/9.0)) { Output = CropResize(Source, 0,1080) }
else if (Aspect > (16.0/9.0)) { Output = CropResize(Source, 1920,0) }
else { Output = CropResize(Source, 1920,1080) }

Output

The above assumes none of the sources are anamorphic. If they are it can still be done, but the above script would need to be modified to account for the source sample aspect ratio so the video is resized correctly.
If you need to convert the colorimetry, check the help file, as the function can do it automatically for standard dynamic range video.

Or you could turn the above script into a function:

function AutoResize(clip Source) {

W = width(Source)
H = height(Source)
Aspect = float(W) / float(H)

if (Aspect < (16.0/9.0)) { Output = CropResize(Source, 0,1080) }
else if (Aspect > (16.0/9.0)) { Output = CropResize(Source, 1920,0) }
else { Output = CropResize(Source, 1920,1080) }

return Output }

And then when it's loaded, just use this in your script:
AutoResize(Source)

EHarlen
30th April 2026, 14:06
This is exactly what I'm talking about.

AVISource("C:\Users\Administrator\Downloads\File\sample.avi")
Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)

But I need the following script for some reason.

AVISource("C:\Users\Administrator\Downloads\File\s ample.avi").Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)


https://forum.videohelp.com/threads/420463-Automatically-Resize-a-Video#post2796339

StainlessS
30th April 2026, 20:36
In Videohelp link, Selur says
"will not work, since cramping everything into one line without taking into account into what that line that actually means,..."
so your [EDIT: final] script line as written in post #6 will not work. (There is no Last clip unless set by source filter AviSource, so cannot use eg Width of last clip because Last dont exist at that point).

Wrong [results of AviSource is passed on as arguement to Lanczos4Resize, Last clip is not set]

AVISource("C:\Users\Administrator\Downloads\File\s ample.avi").Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)


The first two lines from post #6 are correct,

AVISource("C:\Users\Administrator\Downloads\File\s ample.avi")
# Last clip now exists and so CAN use Width and/or Height of Last clip.
Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)

hello_hello
1st May 2026, 08:25
Is it overly OCD of me, not being able to use "width" in a script. I have to type width().

StainlessS
1st May 2026, 10:33
Is it overly OCD of me, not being able to use "width" in a script. I have to type width().
Either is good, however, one of the options may be [ever so slightly] faster than the other, I dont know if so or which.

EDIT: IIRC, use of explicit Last is a bit faster than implicit Last, eg Last.SomeFunction() [or SomeFunction(Last)] faster than SomeFunction(), and Last.Width faster than Width.
Is probable that use of 'Width' scans Local vars table for 'Width' entry, then Global Vars table, then lastly property member of Last clip.
Whereas Last.Width or Last.Width() are pretty explicit in what is intended and probably both fastest of all.

EDIT: 'Fastest' only of any real value in runtime scripts (eg Scriptclip), not when simply 'stitching' together filters into a filter graph prior to frame serving.

No, I don't want borders cropped.
Cropping borders allows for quite a few more options in some media players for display and Aspect Ratio,
eg PotPlayer has about 5 or more different ways of displaying border cropped clips, these alternate display modes are not possible with borders kept intact,
where borders are handled as if part of the video picture.
[The different AR display modes may allow to better fill your display, or even player cropped to totally fill your display without any borders at all]

rgr
1st May 2026, 17:31
This is exactly what I'm talking about.

AVISource("C:\Users\Administrator\Downloads\File\sample.avi")
Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)

But I need the following script for some reason.

AVISource("C:\Users\Administrator\Downloads\File\s ample.avi").Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)


https://forum.videohelp.com/threads/420463-Automatically-Resize-a-Video#post2796339

Maybe this line will suit your needs?

AVISource("C:\Users\Administrator\Downloads\File\s ample.avi")\nLanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)

StainlessS
1st May 2026, 20:55
I dont think that would work, BUT, just a simple SPACE character in place of '\n' would do.
[Think \n would throw an error. (untested, but pretty sure)]

hello_hello
1st May 2026, 21:15
function NewWidth(clip Source) {
return int(float(width(Source)) / float(height(Source)) * 1080.0 / 2.0) * 2 }

AVISource("sample.avi")
Lanczos4Resize(NewWidth(),1080)

or

function Auto1080p(clip Source) {
NewWidth = int(float(width(Source)) / float(height(Source)) * 1080.0 / 2.0) * 2
return Lanczos4Resize(Source, NewWidth,1080) }

AVISource("sample.avi")
Auto1080p()


or

AVISource("sample.avi")
CropResize(0,1080, Resizer="Lanczos4", Mod=2)

EHarlen
2nd May 2026, 16:31
function Auto1080p(clip Source) {
NewWidth = int(float(width(Source)) / float(height(Source)) * 1080.0 / 2.0) * 2
return Lanczos4Resize(Source, NewWidth,1080) }

AVISource("sample.avi")
Auto1080p()

Thanks.

Gavino
2nd May 2026, 18:20
I dont think that would work, BUT, just a simple SPACE character in place of '\n' would do.
[Think \n would throw an error. (untested, but pretty sure)]
Yes, \n throws an error, as \ can only be used at the beginning or end of a line (as a continuation marker).
(Although you can use \n inside the string passed to Subtitle())

But you don't even need a space - just remove the dot!
This works:
AVISource("C:\Users\Administrator\Downloads\File\s ample.avi")Lanczos4Resize(int(float(Width) / Height * 1080 / 2) * 2, 1080)

StainlessS
2nd May 2026, 22:13
Absolutely big G :)

hello_hello
3rd May 2026, 16:01
I was looking for something in a function today and found myself scrolling by the frame properties section, so a quick copy and paste didn't take me out of my way.

If a source is anamorphic and the source filter adds a sample aspect ratio to frame properties it'll be used to calculate the correct width for resizing to "square pixel" dimensions. Without a SAR in frame properties, it's the same as before.

function Auto1080p(clip Source) {

PropNum = propGetAny(Source, "_SARNum")
PropNum = defined(PropNum) && IsInt(PropNum) ? PropNum : 0
PropDen = propGetAny(Source, "_SARDen")
PropDen = defined(PropDen) && IsInt(PropDen) ? PropDen : 0
IsPropSAR = (PropNum > 0 < PropDen)

NewWidth = int((IsPropSAR ? float(PropNum) / float(PropDen) : 1.0) * \
float(width(Source)) / float(height(Source)) * 1080.0 / 2.0) * 2

Output = Lanczos4Resize(Source, NewWidth,1080)
return !IsPropSAR ? Output : Output.propSet("_SARNum", 1).propSet("_SARDen", 1) }