Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 28th May 2008, 20:15   #61  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Try it with align=9 or -9. align=1,2,3,4,7 doesn't work correctly, the AR is off. The main point of align is that it will stretch-to-fit the image, using 2 different methods: black borders or no black borders. Once that image has been aligned and fitted, i may wish to zoom in or out. zoomFactor will never change the output dimensions, but it will allow you to zoom in or out of those pixels. If you want to change the resolution, use Width and Height. Try out the software that Tac suggested, I liked what i saw.

For your example "input clip 640x480 and we want to select the top left quadrant at its original resolution" It would be
Code:
ZoomBoxer(640, 480, align=1, zoomFactor=100)
2x Zoom would be
Code:
ZoomBoxer(640, 480, align=1, zoomFactor=200)
Which is the same as
Code:
crop(0,0,-320,-240)
BilinearResize(640,480)
Once the resolution/dimensions are set, it will never change.


Using the same example
Code:
crop(0,0,-320,-240)
Would be the same as
Code:
ZoomBoxer(320, 240, align=1, zoomFactor=200)

Hopefully this helps. I can see what you mean though... i would be confused as well, if i didn't know how this was supposed to work.

My trial and error is a little overstated... i have about 3 pages of notes/calculations, it was trial and error in that, oh this should work... and it does except when doing "this". I can see why some commercial software packages only operate at a given resolution, makes life easy. But where i placed the *2.0 was purely guesswork.... i knew that it has to be twice as much because the other side of the image is not being scaled by the zoomFactor.




I think you where suggesting that
Code:
ZoomBoxer(160, 120, align=1, zoomFactor=100)
would be the same as
Code:
Crop(0,0,-480,-360)
where as right now it behaves like
Code:
BilinearResize(160,120)
And in order to get the desired effect as the crop line.
Code:
ZoomBoxer(160, 120, align=1, zoomFactor=400)
A fairly simple calculation of the input and output dimensions can make the zoom factor behave in the other manner. 640/160 = 4; 4*100 = 400.

Last edited by mikeytown2; 28th May 2008 at 21:22.
mikeytown2 is offline   Reply With Quote
Old 29th May 2008, 01:43   #62  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Sorry, I had forgotten you already said that align=1 wasn't working yet. Tried with align=9 and it works as you describe.

I probably got my terminology wrong too - by 'original resolution' I meant 'without resizing/resampling', and this would always correspond in my scheme to zoomFactor=100, regardless of input and output sizes. (In both schemes the output frame size is fixed by the corresponding parameters - supplied or defaulted).

My '640x480 top left quadrant' example corresponds to
Code:
ZoomBoxer(320, 240, align=1, zoomFactor=100)
in my scheme but zoomFactor=200 in yours.

Your final examples with output 160x120 do correctly reflect my suggestion and show how it differs from yours.
I now understand how you mean it to work, but it still seems counter-intuitive to me that (at least in this case) crop without resize corresponds to a zoom of 400 whereas actual resize equates to zoom=100. That's because I see zoom as something to be applied to the input (like the Zoom plugin) whereas you intend it (oddly, IMHO) to be applied to the 'stretched-to-fit' clip (a purely conceptual intermediate output).
This makes it harder to figure out what value of zoomFactor to use when the input and output sizes differ, especially if one is not a simple multiple of the other.

That plus I feel it would be better to separate the two different sorts of zooming as I described.

(BTW In all this I've been thinking purely about usability - I haven't considered whether my scheme makes the implementation any easier or harder.)
Gavino is offline   Reply With Quote
Old 29th May 2008, 02:00   #63  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Negative values in zoomFactor is the zoom of the pixels, positive values in zoomFactor is the zoom of the frame. The code for x2,y2 is quite odd... but it seems to work for the tests that I put it through. Had to map it out, then create a formula to match the offset. As for why *2.0 in x1,y1 works... dumb luck?

Please test this sucker out. It's good to go, as far as I can tell.


Code:
A = ColorBars().Crop(10, 20, -30, -400).ConvertToYV12()
B = ColorBars().invert().FlipHorizontal().Crop(10, 20, -300, -40).ConvertToYV12()
C = ColorBars().FlipVertical().Crop(10, 200, -30, -40).ConvertToYV12()
D = ColorBars().invert().FlipVertical().FlipHorizontal().Crop(100, 20, -30, -40).ConvertToYV12()
E = ImageReader("testp2cz4.png",0,0)
E1 = E.ConvertToYV12().AssumeFPS("ntsc_video")
Global W = 640
Global H = 480
Global DAR = 0 #16.0/9.0
Global Resize = "BilinearResize"

SplitScreener(W, H, 8, A, B, C, D, ZoomToFill=1).Trim(0,-1).KillAudio()
last + SplitScreener(W, H, 8, A, B, C, D, ZoomToFill=-1).Trim(0,-1).KillAudio()

last + TestC(E1)


#Try different image
E = ImageReader("traingr4.jpg",0,0)
E2 = E.ConvertToYV12().AssumeFPS("ntsc_video")
Global DAR = 16.0/9.0


last + TestC(E2)

Return Last
 
#E1.ZoomBoxer(W,H, Resize, DisplayAR=0, Align=1, zoomFactor=-100, panX=0, panY=0)


Function TestC(Clip E)
{
	TestA(E,-1)
	last + TestA(E,-2)
	last + TestA(E,-3)
	last + TestA(E,-4)
	last + TestA(E,-5)
	last + TestA(E,5)
	last + TestA(E,-6)
	last + TestA(E,-7)
	last + TestA(E,-8)
	last + TestA(E,-9)

	last + TestB(E, 25)
	last + TestB(E, 50)
	last + TestB(E, 75)
}


Function TestA(clip E, int al)
{
	E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=100, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=75, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=50, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=25, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=12.5, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=6.25, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=3.125, panX=0, panY=0)
	
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=75, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=100, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=200, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=400, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=600, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=800, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=2000, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=al, zoomFactor=20000, panX=0, panY=0)
}

Function TestB(clip E, int zf)
{
	E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-5, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-1, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-3, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-7, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-9, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-2, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-4, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-6, zoomFactor=zf, panX=0, panY=0)
	last + E.ZoomBoxer(W,H, Resize, DisplayAR=DAR, Align=-8, zoomFactor=zf, panX=0, panY=0)

}





Function ZoomBoxer(clip c, int "width", int "height", string "ResizeMethod", float "DisplayAR", int "Align", float "zoomFactor", float "panX", float "panY", int "color", int "IgnoreAR")
{
	#set defaults
	ResizeMethod = Default(ResizeMethod, "BilinearResize")
	IgnoreAR = Default(IgnoreAR, 1)
	color = Default(color, $000000)
	width = Default(width, c.width())
	height = Default(height, c.height())
	Align = Default(Align, 0)
	zoomFactor = Default(zoomFactor, 100.0)
	#zoomFactor = -(Log(zoomFactor*0.01)/Log(4))
	panX = Default(panX, 0)
	panY = Default(panY, 0)
	
	modzoom = Max(Float(c.width())/Float(width),Float(c.height())/Float(height))
	zoomFactor = zoomFactor<0 ? (abs(zoomFactor)/100.0)*modzoom : (abs(zoomFactor)/100.0)
	SourceAR = float(c.width())/float(c.height())
	FinalAR = float(width)/float(height)
	DisplayAR = Default(DisplayAR, Float(c.width())/Float(c.height()))
	DisplayAR = DisplayAR == 0 ? Float(c.width())/Float(c.height()) : DisplayAR
	
	#If Align=5 or -5 then center clip. -5: Add borders. 5: Crop.
	#Display Aspect Ratio = Final Output Ratio. No Change, Show All Pixels
	#Display Aspect Ratio > Final Output Ratio. Add Height or Crop Width 
	#Display Aspect Ratio < Final Output Ratio. Add Width or Crop Height 
	EvalString = 
	\   Align<>0 && DisplayAR==FinalAR ?
	\ "x1=0" + "
	   x2="  + String(c.width()) + "
	   y1=0" + "
	   y2="  + String(c.height()) + "" 
	   
	   
	\ : (Align==-5 || Align==-4 || Align==-6) && DisplayAR>FinalAR ?
	\ "y1=" + String(0 - ((height*DisplayAR-width)/2.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height() + ((height*DisplayAR-width)/2.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width())
	\ : (Align==5 || Align==2 || Align==8) && DisplayAR>FinalAR ?
	\ "x1=" + String(0 + ((height-width/DisplayAR)/2.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width() - ((height-width/DisplayAR)/2.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + "" 
	\ : (Align==-5 || Align==-2 || Align==-8)  && DisplayAR<FinalAR ?
	\ "x1=" + String(0 - ((width/DisplayAR-height)/2.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width() + ((width/DisplayAR-height)/2.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""
	\ : (Align==5 || Align==4 || Align==6)  && DisplayAR<FinalAR  ?
	\ "y1=" + String(0 + ((width-height*DisplayAR)/2.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height() - ((width-height*DisplayAR)/2.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width()) 


	\ : (Align==-1 || Align==-2 || Align==-3) && DisplayAR>FinalAR ?
	\ "y1=" + String(0) + "
	   y2=" + String(c.height() + ((height*DisplayAR-width)/1.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width())
	\ : (Align==-1 || Align==-4 || Align==-7)  && DisplayAR<FinalAR ?
	\ "x1=" + String(0) + "
	   x2=" + String(c.width() + ((width/DisplayAR-height)/1.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""
	\ : (Align==-9 || Align==-8 || Align==-7) && DisplayAR>FinalAR ?
	\ "y1=" + String(0 - ((height*DisplayAR-width)/1.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height()) + "
	   x1=0" + "
	   x2=" + String(c.width())
	\ : (Align==-9 || Align==-6 || Align==-3)  && DisplayAR<FinalAR ?
	\ "x1=" + String(0 - ((width/DisplayAR-height)/1.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width()) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""


	\ : (Align==2 || Align==1 || Align==3) && DisplayAR<FinalAR  ?
	\ "y1=" + String(0) + "
	   y2=" + String(c.height() - ((width-height*DisplayAR)/1.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width()) 
	\ : (Align==8 || Align==7 || Align==9) && DisplayAR<FinalAR  ?
	\ "y1=" + String(0 + ((width-height*DisplayAR)/1.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height()) + "
	   x1=0" + "
	   x2=" + String(c.width()) 
	\ : (Align==4 || Align==1 || Align==7) && DisplayAR>FinalAR ?
	\ "x1=" + String(0) + "
	   x2=" + String(c.width() - ((height-width/DisplayAR)/1.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + "" 
	\ : (Align==6 || Align==3 || Align==9) && DisplayAR>FinalAR ?
	\ "x1=" + String(0 + ((height-width/DisplayAR)/1.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width()) + "
	   y1=0" + "
	   y2=" + String(c.height()) + "" 



	\ : ""
	Eval(EvalString)
	
	#Take Crop Like Input
	x2 = x2<=x1 && x2 < 0 ? c.width() + x2 : x2
	y2 = y2<=y1 && y2 < 0 ? c.height() + y2 : y2
	
	#Check if x2 or y2 needs to be calculated
	Assert( ((x2==x1) && (y2==y1))==False, "x2 [" + String(x2) + "] or y2 [" + String(y2) + "] needs a value that is different from x1 [" + String(x1) + "] or y1 [" + String(y1) + "]")
	y2 = (y2==y1) ? (((x2-x1)/FinalAR)/(SourceAR/DisplayAR) + y1) : y2
	x2 = (x2==x1) ? (((y2-y1)*FinalAR)*(SourceAR/DisplayAR) + x1) : x2
	
	SubString = "Align=" + String(Align) + "  zoomFactor=" + String(zoomFactor*100) + "  panX=" + String(panX) + "  panY=" + String(panY)
	
	#Calc Pan Factor
	x1 = x1+panX
	y1 = y1+panY
	x2 = x2+panX
	y2 = y2+panY
	
	#Calc Zoom Factor
	BoxAR = Float(x2-x1)/Float(y2-y1)

	CenterX = (x2-x1)/2.0
	CenterY = (y2-y1)/2.0
	
	CenterY = (Align<0 && DisplayAR>FinalAR)? CenterY*(FinalAR/DisplayAR): (Align>0 && DisplayAR<FinalAR)? CenterY*(FinalAR/DisplayAR): CenterY 
	CenterX = (Align>0 && DisplayAR>FinalAR)? CenterX/(FinalAR/DisplayAR): (Align<0 && DisplayAR<FinalAR)? CenterX/(FinalAR/DisplayAR): CenterX
	
	Align = abs(Align)
	sY = " CenterY: " + String(CenterY) + "  y2: " + String(y2) + "  y1: " + String(y1)
	sX = " CenterX: " + String(CenterX) + "  x2: " + String(x2) + "  x1: " + String(x1)
	x1 = (Align==0 || Align==5 || Align==2 || Align==8) && zoomFactor<>1 ? CenterX-((CenterX-x1)/(zoomFactor)) : (Align==3 || Align==6 || Align==9) && zoomFactor<>1 ? CenterX*2.0-((CenterX*2.0-x1)/zoomFactor) : x1
	y1 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY-((CenterY-y1)/(zoomFactor)) : (Align==7 || Align==8 || Align==9) && zoomFactor<>1 ? CenterY*2.0-((CenterY*2.0-y1)/zoomFactor) : y1
	x2 = (Align==0 || Align==5 || Align==2 || Align==8) && zoomFactor<>1 ? CenterX+((x2-CenterX)/(zoomFactor)) : (Align==7 || Align==4 || Align==1) && zoomFactor<>1 ? CenterX+((x2-CenterX)/(zoomFactor))+((100.0/(zoomFactor*100.0))-1)*CenterX : x2
	y2 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY+((y2-CenterY)/(zoomFactor)) : (Align==3 || Align==2 || Align==1) && zoomFactor<>1 ? CenterY+((y2-CenterY)/(zoomFactor))+((100.0/(zoomFactor*100.0))-1)*CenterY : y2

	
	
	BoxAR = Float(x2-x1)/Float(y2-y1)
	#Check For Any Unreasonable Inputs
	Assert(x1<x2, "ZoomBox: x1[" + String(x1) + "] point larger then x2 Point[" + String(x2) + "]")
	Assert(y1<y2, "ZoomBox: y1[" + String(y1) + "] point larger then y2 Point[" + String(y2) + "]")
	Assert(IgnoreAR>0 || BoxAR == FinalAR, "ZoomBox: Box Aspect Ratio [" + String(BoxAR) + "] does not equal clip output Aspect Ratio [" + string(FinalAR) + "]")
	
	#Pad clip so resizer interpolates from border when zooming out. 64 for spline64
	#Conditional Borders... only add if it's going to be used.
	borderSize = 64
	borderLeft   = x1 < 0 ? borderSize : 0
	borderTop    = y1 < 0 ? borderSize : 0
	borderRight  = x2 > c.width() ? borderSize : 0
	borderBottom = y2 > c.height() ? borderSize : 0
	c = c.AddBorders(borderLeft,borderTop,borderRight,borderBottom,color)
	
	#Do it
	c = Eval(ResizeMethod + "(c, " + String(Round(width)) + ", " + String(Round(height)) + ", src_left=" + String(x1+borderLeft) + ", src_top=" + String(y1+borderTop) + ", src_width=" + String(x2-x1) + ", src_height=" + String(y2-y1) + ")")	
	
	c
	Subtitle("BoxAR " + String(BoxAR) +  "   " + String(x1) + ", " + String(y1) + "    " + String(x2) + ", " + String(y2) + "  " + String())
	Subtitle(SubString, y=100)
	Subtitle(sY, y=140)
	Subtitle(sX, y=160)
}







function SplitScreener(int Width, int Height, int Border, clip A, clip B, clip C, clip D, int "ZoomToFill", string "ResizeMethod", bool "AudioMix")
{
	#Set Defaults
	ResizeMethod = Default(ResizeMethod, "BilinearResize")
	AudioMix = Default(AudioMix, true)
	ZoomToFill = Default(ZoomToFill, -1)
	
	#Check Inputs
	Assert(ZoomToFill==1 || ZoomToFill==-1, "ZoomToFill must be 1 or -1. Input of " + String(ZoomToFill) + " doesn't work")
	
	
	#Set Borders
	BorderH = Border
	BorderW = Border
	
	#Set Width and Height of individual clips
	NewW = Round(float(Width)/2.0 - float(BorderW)*1.5)
	NewH = Round(float(Height)/2.0 - float(BorderH)*1.5)
	NewAR = Float(NewW)/Float(NewH)
	OutAR = Float(Width)/Float(Height)
	
	#Process Video
	A = A.ZoomBoxer(NewW, NewH, ResizeMethod, Float(A.width())/Float(A.height())*(NewAR/OutAR), ZoomToFill*(9))
	A = A.AddBorders(BorderW, BorderH, 0, 0)
	B = B.ZoomBoxer(NewW, NewH, ResizeMethod, Float(B.width())/Float(B.height())*(NewAR/OutAR), ZoomToFill*(7))
	B = B.AddBorders(BorderW, BorderH, 0, 0)
	C = C.ZoomBoxer(NewW, NewH, ResizeMethod, Float(C.width())/Float(C.height())*(NewAR/OutAR), ZoomToFill*(3))
	C = C.AddBorders(BorderW, BorderH, 0, 0)
	D = D.ZoomBoxer(NewW, NewH, ResizeMethod, Float(D.width())/Float(D.height())*(NewAR/OutAR), ZoomToFill*(1))
	D = D.AddBorders(BorderW, BorderH, 0, 0)
	
	#Merge Clips
	X = StackHorizontal(A, B).AddBorders(0,0,BorderW,0)
	Y = StackHorizontal(C, D).AddBorders(0,0,BorderW,0)
	StackVertical(X, Y).AddBorders(0,0,0,BorderH).KillAudio()
	
	#Fix Audio
	LongestClip = Int(Max(Framecount(A), Framecount(B), Framecount(C), Framecount(D)))
	A = (Framecount(A) <> LongestClip) ? A ++ BlankClip(A, LongestClip-Framecount(A)) : A
	B = (Framecount(B) <> LongestClip) ? B ++ BlankClip(B, LongestClip-Framecount(B)) : B
	C = (Framecount(C) <> LongestClip) ? C ++ BlankClip(C, LongestClip-Framecount(C)) : C
	D = (Framecount(D) <> LongestClip) ? D ++ BlankClip(D, LongestClip-Framecount(D)) : D
	
	#Mix Audio
	Sound = (AudioMix) ? MergeChannels(MixAudio(ConvertToMono(A).Amplify(0.49), ConvertToMono(C).Amplify(0.49)), MixAudio(ConvertToMono(B).Amplify(0.49), ConvertToMono(D).Amplify(0.49))):
		\ MergeChannels(GetLeftChannel(A), GetRightChannel(A), GetLeftChannel(B), GetRightChannel(B), GetLeftChannel(C), GetRightChannel(C), GetLeftChannel(D), GetRightChannel(D))
	AudioDub(last, Sound)
}
mikeytown2 is offline   Reply With Quote
Old 29th May 2008, 11:15   #64  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
This is the final code (for now) of zoombox(), unless there is a simple error to correct. I will not change the first post until I port it over to KBE(). I put back x1,y1,x2,y2 and added various checks of the input (assert x1,y1,x2,y2 doesn't work...). Align also works (controls where it is zoomed) when you specify the box (x1, y1, x2 and/or y2) and the zoomfactor. Negative zoomfactor if off a little when converting AR, its not a show stopper, so unless it's an easy fix, I'm going to ignore it for now.
Code:
# ZoomBox() - May 29th, 2008
#  Put a "box" around a clip. Box can be used to zoom in or out. Accepts Any Colorspace. Can correct for DAR (Display Aspect Ratio).
# 
#
# Inputs
#   clip c: Accepts Any Colorspace.
#  Optional Parameters:
#   int width: output width
#   int height: output height
#   string ResizeMethod: name of resize function. Default = BilinearResize
#   float DisplayAR: Set the Output Aspect Ratio. If 0 then it uses the source aspect ratio (needed for animate).
#
#  Mode 2 - Align clip
#   int Align: -9 to +9 (0=Do not use Align). Positive values - fit with no black borders, may crop clip. Negative values - fit with black borders, may letterbox clip.
#                1:top left.     2:top center.     3:top right. 
#                4:middle left.  5:middle center.  6:middle bottom. 
#                7:bottom left.  8:bottom center.  9:bottom right.
#
#  Mode 1 - Coordinates for ZoomBox:
#   float x1: upper left x cord (required)
#   float y1: upper left y cord (required)
#   float x2: lower right x cord (optional)
#   float y2: lower right y cord (optional)
#               x2 and/or y2 must be defined when using Mode 1
#               when omitting x2 or y2, it will calculate the missing value, with the Aspect Ratio in mind.
#
#  float zoomFactor: 100 = 100%, ect... 
#                      Negative values is the zoom of the pixels, positive values is the zoom of the frame. 
#                      When converting AR, this isn't perfect.
#  float panX: shift the clip x pixels. Value in source pixels. - left, + right
#  float panY: shift the clip x pixels. Value in source pixels. - up, + down
#  int color: Color of letterbox border. Default: $000000 (Black).
#  int IgnoreAR: 1 - Ignore Warnings; 0 - Show Warnings. Default=1, Ignore AR waring
# 
#
# Notes
#  Aspect ratio for output and box(x1,y1,x2,y2) should be the same, unless you want to distort the clip.
#  Default behavior is to center clip by adding borders (Align=-5).
#  Useful for resizing clip sources (like pictures) to match the dimension of another clip.
#  If you specify Align (Mode 2) and x1,y1,x2,y2 (Mode 1), Mode 1 will be used and the align will control the position of the zoomFactor.
#  Mode 1 (x1,y1,x2,y2) can take values from a crop operation. x2 and y2 must be negative though; so if x2 or y2 equals 0, replace 0 with -0.00001.

Function ZoomBox(clip c, int "width", int "height", string "ResizeMethod", float "DisplayAR", int "Align", float "x1", float "y1", float "x2", float "y2", float "zoomFactor", float "panX", float "panY", int "color", int "IgnoreAR")
{
	#Set Defaults
	width = Default(width, c.width())
	height = Default(height, c.height())
	ResizeMethod = Default(ResizeMethod, "BilinearResize")
	DisplayAR = Default(DisplayAR, Float(c.width())/Float(c.height()))
	Align = Default(Align, -5) #Align=-5 (center and add borders to fit).
	zoomFactor = Default(zoomFactor, 100.0)
	panX = Default(panX, 0)
	panY = Default(panY, 0)
	color = Default(color, $000000)
	IgnoreAR = Default(IgnoreAR, 1)
	
	
	#Calc Defaults
	SourceAR = float(c.width())/float(c.height())
	FinalAR = float(width)/float(height)
	DisplayAR = DisplayAR==0 ? Float(c.width())/Float(c.height()) : DisplayAR
	modzoom = Max(Float(c.width())/Float(width),Float(c.height())/Float(height))
	zoomFactor = zoomFactor<0 ? (abs(zoomFactor)/100.0)*modzoom : (abs(zoomFactor)/100.0)
	
	#Check Inputs
	Assert(zoomFactor<>0, "ZoomBox: zoomFactor can not be zero.")
	Assert(DisplayAR>=0, "ZoomBox: DisplayAR [" + String(DisplayAR) + "] must be positive.")
	Assert((Defined(x1) && Defined(y1) && (Defined(x2) || Defined(y2))) || !(Defined(x1) && Defined(y1) && Defined(x2) && Defined(y2)), "ZoomBox: when using Mode 1, you must define x1,y1, x2 and/or y2")
	Assert(Align<9 || Align>-9, "ZoomBox: Align [" + String(Align) + "] should be between -9 and 9.")
	
	
	#If Align=5 or -5 then center clip. -5: Add borders. 5: Crop. "Mode 2"
	#Display Aspect Ratio = Final Output Ratio. No Change, Show All Pixels
	#Display Aspect Ratio > Final Output Ratio. Add Height or Crop Width 
	#Display Aspect Ratio < Final Output Ratio. Add Width or Crop Height 
	EvalString = 
	\   Align<>0 && DisplayAR==FinalAR ?
	\ "x1=0" + "
	   x2="  + String(c.width()) + "
	   y1=0" + "
	   y2="  + String(c.height()) + ""
	
	
	\ : (Align==-5 || Align==-4 || Align==-6) && DisplayAR>FinalAR ?
	\ "y1=" + String(0 - ((height*DisplayAR-width)/2.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height() + ((height*DisplayAR-width)/2.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width())
	\ : (Align==5 || Align==2 || Align==8) && DisplayAR>FinalAR ?
	\ "x1=" + String(0 + ((height-width/DisplayAR)/2.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width() - ((height-width/DisplayAR)/2.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + "" 
	\ : (Align==-5 || Align==-2 || Align==-8)  && DisplayAR<FinalAR ?
	\ "x1=" + String(0 - ((width/DisplayAR-height)/2.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width() + ((width/DisplayAR-height)/2.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""
	\ : (Align==5 || Align==4 || Align==6)  && DisplayAR<FinalAR  ?
	\ "y1=" + String(0 + ((width-height*DisplayAR)/2.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height() - ((width-height*DisplayAR)/2.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width()) + ""
	
	
	\ : (Align==-1 || Align==-2 || Align==-3) && DisplayAR>FinalAR ?
	\ "y1=" + String(0) + "
	   y2=" + String(c.height() + ((height*DisplayAR-width)/1.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width())
	\ : (Align==-1 || Align==-4 || Align==-7)  && DisplayAR<FinalAR ?
	\ "x1=" + String(0) + "
	   x2=" + String(c.width() + ((width/DisplayAR-height)/1.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""
	\ : (Align==-9 || Align==-8 || Align==-7) && DisplayAR>FinalAR ?
	\ "y1=" + String(0 - ((height*DisplayAR-width)/1.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height()) + "
	   x1=0" + "
	   x2=" + String(c.width())
	\ : (Align==-9 || Align==-6 || Align==-3)  && DisplayAR<FinalAR ?
	\ "x1=" + String(0 - ((width/DisplayAR-height)/1.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width()) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""
	
	
	\ : (Align==2 || Align==1 || Align==3) && DisplayAR<FinalAR  ?
	\ "y1=" + String(0) + "
	   y2=" + String(c.height() - ((width-height*DisplayAR)/1.0)*(c.height()/Float(width))) + "
	   x1=0" + "
	   x2=" + String(c.width()) 
	\ : (Align==8 || Align==7 || Align==9) && DisplayAR<FinalAR  ?
	\ "y1=" + String(0 + ((width-height*DisplayAR)/1.0)*(c.height()/Float(width))) + "
	   y2=" + String(c.height()) + "
	   x1=0" + "
	   x2=" + String(c.width()) 
	\ : (Align==4 || Align==1 || Align==7) && DisplayAR>FinalAR ?
	\ "x1=" + String(0) + "
	   x2=" + String(c.width() - ((height-width/DisplayAR)/1.0)*(c.width()/Float(height))) + "
	   y1=0" + "
	   y2=" + String(c.height()) + "" 
	\ : (Align==6 || Align==3 || Align==9) && DisplayAR>FinalAR ?
	\ "x1=" + String(0 + ((height-width/DisplayAR)/1.0)*(c.width()/Float(height))) + "
	   x2=" + String(c.width()) + "
	   y1=0" + "
	   y2=" + String(c.height()) + ""
	
	
	\ : ""
	Defined(x1) ? nop() : Eval(EvalString)

		
	#Set Optional parameters "Mode 1"
	x2 = Defined(x1) && !Defined(x2) ? x1 : x2
	y2 = Defined(y1) && !Defined(y2) ? y1 : y2
	
	
	#For non Align Input "Mode 1"
	#Take Crop Like Input
	x2 = x2<=x1 && x2<0 ? c.width() + x2 : x2
	y2 = y2<=y1 && y2<0 ? c.height() + y2 : y2
	
	#Check if x2 or y2 needs to be calculated "Mode 1"
	Assert( ((x2==x1) && (y2==y1))==False, "x2 [" + String(x2) + "] or y2 [" + String(y2) + "] needs a value that is different from x1 [" + String(x1) + "] or y1 [" + String(y1) + "]")
	y2 = (y2==y1) ? (((x2-x1)/FinalAR)/(SourceAR/DisplayAR) + y1) : y2
	x2 = (x2==x1) ? (((y2-y1)*FinalAR)*(SourceAR/DisplayAR) + x1) : x2
	
	
	
	#Calc Pan Factor
	x1 = x1+panX
	y1 = y1+panY
	x2 = x2+panX
	y2 = y2+panY
	
	#Calc Zoom Factor
	CenterX = (x2-x1)/2.0
	CenterY = (y2-y1)/2.0
	CenterY = (Align<0 && DisplayAR>FinalAR)? CenterY*(FinalAR/DisplayAR): (Align>0 && DisplayAR<FinalAR)? CenterY*(FinalAR/DisplayAR): CenterY 
	CenterX = (Align>0 && DisplayAR>FinalAR)? CenterX/(FinalAR/DisplayAR): (Align<0 && DisplayAR<FinalAR)? CenterX/(FinalAR/DisplayAR): CenterX
	
	Align = abs(Align)
	x1 = (Align==0 || Align==5 || Align==2 || Align==8) && zoomFactor<>1 ? CenterX-((CenterX-x1)/(zoomFactor)) : (Align==3 || Align==6 || Align==9) && zoomFactor<>1 ? CenterX*2.0-((CenterX*2.0-x1)/zoomFactor) : x1
	y1 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY-((CenterY-y1)/(zoomFactor)) : (Align==7 || Align==8 || Align==9) && zoomFactor<>1 ? CenterY*2.0-((CenterY*2.0-y1)/zoomFactor) : y1
	x2 = (Align==0 || Align==5 || Align==2 || Align==8) && zoomFactor<>1 ? CenterX+((x2-CenterX)/(zoomFactor)) : (Align==7 || Align==4 || Align==1) && zoomFactor<>1 ? CenterX+((x2-CenterX)/(zoomFactor))+((100.0/(zoomFactor*100.0))-1)*CenterX : x2
	y2 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY+((y2-CenterY)/(zoomFactor)) : (Align==3 || Align==2 || Align==1) && zoomFactor<>1 ? CenterY+((y2-CenterY)/(zoomFactor))+((100.0/(zoomFactor*100.0))-1)*CenterY : y2
	
	
	
	BoxAR = Float(x2-x1)/Float(y2-y1)
	#Check for any unreasonable inputs before resize opperation
	Assert(x1<x2, "ZoomBox: x1[" + String(x1) + "] point larger then x2 Point[" + String(x2) + "]")
	Assert(y1<y2, "ZoomBox: y1[" + String(y1) + "] point larger then y2 Point[" + String(y2) + "]")
	Assert(IgnoreAR>0 || BoxAR == FinalAR, "ZoomBox: Box Aspect Ratio [" + String(BoxAR) + "] does not equal clip output Aspect Ratio [" + string(FinalAR) + "]")
	
	#Pad clip so resizer interpolates from border when zooming out.
	#Conditional Borders... only add if it's going to be used. Max Border size is size of input frame. Prevents "streaking" when zooming out alot.
	borderLeft   = x1 < 0 ? Int(Min(Abs(x1),c.width())) : 0
	borderTop    = y1 < 0 ? Int(Min(Abs(y1),c.height())) : 0
	borderRight  = x2 > c.width() ? Int(Min(x2-c.width(),c.width())) : 0
	borderBottom = y2 > c.height() ? Int(Min(y2-c.height(),c.height())) : 0
	c = c.AddBorders(borderLeft,borderTop,borderRight,borderBottom,color)
	
	#Do it! Yes there are only 2 lines that directly act upon the clip.
	c = Eval(ResizeMethod + "(c, " + String(Round(width)) + ", " + String(Round(height)) + ", src_left=" + String(x1+borderLeft) + ", src_top=" + String(y1+borderTop) + ", src_width=" + String(x2-x1) + ", src_height=" + String(y2-y1) + ")")	
	
	c
}
mikeytown2 is offline   Reply With Quote
Old 30th May 2008, 01:05   #65  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
I haven't had time to study or try out your latest updates, but here's something that has just struck me - you don't need to construct your long eval strings for x1 (etc) bit-by-bit - just write them as normal expressions within a single (but still multi-line) string literal.

For example,
Code:
EvalString = Align<>0 && DisplayAR==FinalAR ?
\ "x1=0" + "
   x2="  + String(c.width()) + "
   y1=0" + "
   y2="  + String(c.height()) + ""
# ... etc
can be written simply as
Code:
EvalString = Align<>0 && DisplayAR==FinalAR ?
\ "x1=0
   x2=c.width()
   y1=0
   y2=c.height()"
# ... etc
which is certainly more readable and easier to maintain, almost like a 'real' program.
Gavino is offline   Reply With Quote
Old 2nd June 2008, 01:52   #66  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
KenBurnsEffect/ZoomBox Updated

KenBurnsEffect/ZoomBox Changes
  • Align Added - Much easier to use now!
  • PanX/Y Added
  • zoomFactor Added
  • letterbox color can be set
  • KBE() should be slightly faster, with default settings, as a result of breaking up the function.
  • Read function headers for more details.



Quote:
Originally Posted by Gavino View Post
almost like a 'real' program
It's Getting there, split this up into more functions, less repeating code. Thanks for the tip, should make the code slightly faster.


Huge example has been updated as well.
mikeytown2 is offline   Reply With Quote
Old 2nd June 2008, 15:35   #67  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Nice work, mikeytown2, it's looking good.

I like the idea of your your CalcBox function, which shows how to effectively get multiple return values (by returning a string containing multiple assignments which is then Eval'd). Cool.
Gavino is offline   Reply With Quote
Old 4th June 2008, 06:45   #68  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Been thinking about format conversions. Looked at this guide as well as this calculator.

ZoomBox can do subpixel Resizes, thus no DAR error. This is what i got, I've never dealt with PAL, so help me out!
Code:
ntscdar_W = (4752.0/4739.0) / (4320.0/4739.0) * (486.0/486.0) * 640.0
ntscdar_H = (486.0/486.0) * 480
ntscDAR = ntscdar_W/ntscdar_H
ColorBars().Trim(0,-1).KillAudio().AssumeFPS(30)
a = BlankClip(last,1,720,480).Subtitle("""640×480 "industry standard" square pixels to 720×480 ITU-R BT.601 pixels""", align=5)
b = BilinearResize(720,480).Subtitle("Incorrect conversion from square pixel 640x480 to DVD frame size, 720x480", align=5)
c = BilinearResize(704,480).AddBorders(8,0,8,0).Subtitle(""" "Correct" conversion from square pixel 640x480 to DVD frame size, 720x480""", align=5)
d = ZoomBox(720,480, DisplayAR=ntscDAR, Align=-5).Subtitle("Correct conversion from square pixel 640x480 to DVD frame size, 720x480  DAR=" + String(ntscDAR), align=5)
e = ZoomBox(720,480, DisplayAR=ntscDAR, Align=5).Subtitle("Correct conversion from square pixel 640x480 to DVD frame size, 720x480  DAR=" + String(ntscDAR), align=5)
y = a+b+c+d+e

paldar_W = (768.0/767.0) / (4320.0/4739.0) * (486.0/576.0) * 768.0
paldar_H = (486.0/576.0) * 576.0
palDAR = paldar_W/paldar_H

f = BlankClip(last,1,720,480).Subtitle(""" "Industry standard" 625/50 square-pixel to 720×480 ITU-R BT.601 pixels""", align=5)
ImageReader("180pxpm5544768zx5.png",0,0,Pixel_type="RGB32").AssumeFPS(30)
g = BilinearResize(720,480).Subtitle("Incorrect conversion from square pixel 768x576 to DVD frame size, 720x480", align=5)
h = BilinearResize(712,486).crop(0,3,0,-3).addborders(4,0,4,0).Subtitle(""" "Correct" conversion from square pixel 768x576 to DVD frame size, 720x480""", align=5)
i = ZoomBox(720,480, DisplayAR=palDAR, Align=5).Subtitle(" Correct conversion from square pixel 768x576 to DVD frame size, 720x480  DAR=" + String(palDAR), align=5)
j = ZoomBox(720,480, DisplayAR=palDAR, Align=-5).Subtitle(" Correct conversion from square pixel 768x576 to DVD frame size, 720x480  DAR=" + String(palDAR), align=5)
z = f+g+h+i+j

y+z

http://en.wikipedia.org/wiki/Test_card



Also minor update to ZoomBox, should work when DisplayAR is not given.

Last edited by mikeytown2; 5th June 2008 at 22:08.
mikeytown2 is offline   Reply With Quote
Old 5th June 2008, 10:43   #69  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Played around with the idea of emulating a multiplane camera. If i can make a function based off of starting and ending "depth" of every clip, and let the code calc the zooms and pans, would it be worth it? Anyway, here are the Pic's I used and the corresponding code. I call this Paradise Drums...




Code:
Width = 640
Height = 480
Frames = 199


Background = ImageReader("waterfall12803cboflxu2rj8.jpg", pixel_type="RGB32").Trim(0,Frames).KenBurnsEffect(width=width, height=height, startAlign=5, endAlign=5, endZoomFactor=120, endPanY=100)
DrumA = ImageReader("drumkitan5.png", pixel_type="RGB32").Trim(0,Frames).KenBurnsEffect(startAlign=-7, startZoomFactor=50, endAlign=-7, endZoomFactor=60, endPanX=140, endPanY=-140, width=width, height=height)
DrumB = ImageReader("55gallonng2.png", pixel_type="RGB32").Trim(0,Frames).KenBurnsEffect(startAlign=-9, startZoomFactor=50, endPanX=-360, endPanY=-360, endAlign=-9, endZoomFactor=120, width=width, height=height)

Background = Background.Animate(0,Frames-20,"BigBlur",1.58,-0.05)
DrumA = DrumA.Animate(0,Frames-100,"BigBlur",1.58,0.0).Animate(Frames-99,Frames,"BigBlur",0.0,1.58)
DrumB = DrumB.Animate(0,Frames-100,"BigBlur",0.0,1.58)

Layer(Background, DrumA)
Layer(last, DrumB)


Function BigBlur(clip C, float x)
{
c
return Blur(x).Blur(x).Blur(x).Blur(x).Blur(x).Blur(x).Blur(x).Blur(x).Blur(x)
}
Blur is unreliable if you chain it too many times, thus i think a reside down and back up will probably be the best option...

Got idea from here
http://www.reiji.net/ff-e/features.html


Also I experimented with Reform, but its not sub pixel accurate, image jumps around... DeBarrel works when Animated, but the change vs time spent isn't worth it.
mikeytown2 is offline   Reply With Quote
Old 6th June 2008, 21:22   #70  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
KBE, ZB Updated
  • DisplayAR was incorrectly labeled, and is being replaced by SourceDAR and TargetDAR. Discussion about this

Updated the example so it reflects ready for DVD output. I tested this with HCenc and it looked great when I played it back in MPC.

So here is a quick cheat sheet, for me anyway.
Inputs:
for DV NTSC the SourceDAR=720.0/528.0 or is it 720.0/525.0
HDV SourceDAR = 1920.0/1080.0

Outputs:
DVD width:720, height:480
TargetDAR=4.0/3.0 for DVD
TargetDAR=16.0/9.0 for Anamorphic widescreen DVD
mikeytown2 is offline   Reply With Quote
Old 7th June 2008, 00:47   #71  |  Link
NerdWithNoLife
Registered User
 
NerdWithNoLife's Avatar
 
Join Date: Jul 2007
Posts: 157
I love this idea but I've never gotten the dang thing to work. When I tried the colorbars example it said, "zoom factor cannot be zero."

I've done some very long scripts to accomplish panning in the past so if someone can help me figure out this filter it would be much appreciated.
NerdWithNoLife is offline   Reply With Quote
Old 7th June 2008, 01:00   #72  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Quote:
Originally Posted by NerdWithNoLife View Post
I love this idea but I've never gotten the dang thing to work. When I tried the colorbars example it said, "zoom factor cannot be zero."

I've done some very long scripts to accomplish panning in the past so if someone can help me figure out this filter it would be much appreciated.
The inputs for these groups of functions keep changing; it's the only way to progress. The main issue is the fact that i didn't name the inputs in my past examples.

I'll make up a new colorbars example for ya.
Code:
a = ColorBars().Trim(0,99)

KenBurnsEffect(a, startAlign=5, endAlign=5, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=5, endAlign=1, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=1, endAlign=3, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=3, endAlign=9, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=9, endAlign=7, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=7, endAlign=1, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=1, endAlign=5)

Post some example code, or detailed descriptions and i should be able to give you a hand.

Last edited by mikeytown2; 7th June 2008 at 02:31.
mikeytown2 is offline   Reply With Quote
Old 7th June 2008, 10:34   #73  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Started to take a serious look at Rotation. Here is my script which uses the 3 different ways in AviSynth to rotate a clip

Code:
a = ColorBars().Trim(0,99)

Animate(0, a.framecount()-1,        "Angle", a, float(-500), 1, a, float(510), 1)
last + Animate(0, a.framecount()-1, "Angle", a,  float(510), 1, a, float(520), 1)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 2, a, float(510), 2)
last + Animate(0, a.framecount()-1, "Angle", a,  float(510), 2, a, float(520), 2)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 3, a, float(510), 3)
last + Animate(0, a.framecount()-1, "Angle", a,  float(510), 3, a, float(520), 3)

Function Angle(clip c, float a, int mode)
{
	b = (Round(abs(a)*1000)%360000)/1000.0
	d = a < 0 ? 1-(b/360.0) : b/360.0
	b = a < 0 ? -b : b
	c
	
	mode == 1 ? Zoom(angle="spline(n, " + String(0) + "," + String(a) + ", " + String(1) + "," + String(a) + ", false)") :
	\ mode == 2 ? Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,0.5,0.5,d,0.2) : 
	\ EffectRotation(id=round(-b), cc=$000000)
}
Zoom is the highest quality. PetePanSpinZoom doesn't do subpixel calculations and EffectRotation doesn't take floats. EffectRotation is the slowest, PetePanSpinZoom is the fastest. Zoom appears to be the best choice! PetePanSpinZoom appears to have the side effect of using 100% cpu (in my case, with 2 cores: 50%) when doing nothing.
mikeytown2 is offline   Reply With Quote
Old 7th June 2008, 11:35   #74  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Updated KBE and ZB
KBE can now rotate images

in ZB/KBE pan(XY) now follows the documentation. negative pan is left or up.

Simple demo of zoom, rotate & pan.
Code:
ColorBars().Trim(0,99)
KenBurnsEffect(startAngle=0, endAngle=30, startFrame=19, endFrame=79, usezoomBox=0, endzoomFactor=50, endPanY=-200, endPanX=-100)


rotate appears to operate on the center of the image, after the fact; or at least thats how its coded to work in KBE.
Code:
ColorBars().Trim(0,99)
KenBurnsEffect(startAngle=0, endAngle=360, startFrame=19, endFrame=79, usezoomBox=0, startzoomFactor=50, endzoomFactor=50, endPanY=-200, startPanY=-200)

Last edited by mikeytown2; 7th June 2008 at 11:50.
mikeytown2 is offline   Reply With Quote
Old 8th June 2008, 07:12   #75  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Played around with adding this interlace resize code into KBE/ZB. The quality isn't that good when zooming out because of the black borders. Plus the zoom/pan is only using 1/2 the "frame rate" if you think about it.

Code:
Function ZoomBoxIt(clip c, int width, int height, string ResizeMethod, float x1, float y1, float x2, float y2, int color, bool InterlacedFastLQ)
{
	#Pad clip so resizer interpolates from border when zooming out.
	#Conditional Borders... only add if it's going to be used. Border size is size of input frame. Prevents "streaking" when zooming out alot.
	borderLeft   = x1 < 0 ? c.width():0
	borderTop    = y1 < 0 ? c.height():0
	borderRight  = x2 > c.width() ? c.width():0
	borderBottom = y2 > c.height() ? c.height():0
	c = c.AddBorders(borderLeft,borderTop,borderRight,borderBottom,color)
	
	Shift=(height/(y2-y1)-1.0)*0.25 # Field shift correction
	InterlacedFastLQ ? Eval("""
	c=c.SeparateFields()
	d=c.SelectEven()
	e=c.SelectOdd()
	TF=Eval(ResizeMethod + "(d, " + String(Round(width)) + ", " + String(Round(height/2.0)) + ", src_left=" + String(x1+borderLeft) + ", src_top=" + String((y1+borderTop)/2.0-shift) + ", src_width=" + String(x2-x1) + ", src_height=" + String((y2-y1)/2.0) + ")")
	BF=Eval(ResizeMethod + "(e, " + String(Round(width)) + ", " + String(Round(height/2.0)) + ", src_left=" + String(x1+borderLeft) + ", src_top=" + String((y1+borderTop)/2.0+shift) + ", src_width=" + String(x2-x1) + ", src_height=" + String((y2-y1)/2.0) + ")")
	Interleave(TF, BF).Weave()""") : \
	Eval(ResizeMethod + "(c, " + String(Round(width)) + ", " + String(Round(height)) + ", src_left=" + String(x1+borderLeft) + ", src_top=" + String(y1+borderTop) + ", src_width=" + String(x2-x1) + ", src_height=" + String(y2-y1) + ")")	
}

Thus when using KBE/ZB with interlaced content, and wanting interlaced returned, this is the "general" way to do it. Replace bob() with your favorite bobber for higher quality results.
Code:
AVISource("dv.avi")
AssumeBFF() #set order
bob()
KenBurnsEffect(startFrame=100*2, endFrame=1600*2) #make sure to multiply startFrame and endFrame by 2 since the framerate has doubled.
separatefields()
selectevery(4,0,3)
weave()

Last edited by mikeytown2; 8th June 2008 at 07:19.
mikeytown2 is offline   Reply With Quote
Old 9th June 2008, 02:24   #76  |  Link
NerdWithNoLife
Registered User
 
NerdWithNoLife's Avatar
 
Join Date: Jul 2007
Posts: 157
Quote:
Originally Posted by mikeytown2 View Post
The inputs for these groups of functions keep changing; it's the only way to progress. The main issue is the fact that i didn't name the inputs in my past examples.

I'll make up a new colorbars example for ya.
Aha - it worked. I understand this is still in development so thanks so much for A) working on this project B) helping dummies like me. Can't wait for the rotation capability. People like you make me jealous...
NerdWithNoLife is offline   Reply With Quote
Old 9th June 2008, 02:30   #77  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Quote:
Originally Posted by NerdWithNoLife View Post
Can't wait for the rotation capability.
It's ready! KBE has 2 different ways to do the "dirty work". One way is to animate ZoomBox, the other way is to use zoom.dll. If you set useZoomBox=0, set startAngle and endAngle!

This post has 2 examples using rotate.
http://forum.doom9.org/showthread.ph...66#post1146666
mikeytown2 is offline   Reply With Quote
Old 12th June 2008, 10:36   #78  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Updated KBE/ZB

Added Source/Target PAR to both
Added the ability to not set x1 or y1; you still need 3 out of 4 points defined though in mode 1.

Also changed cubic option on KBE to an int. cubic=0 is the same as cubic=false; cubic=1 is the same as cubic=true. cubic's range is from 0-5 right now. Each option does something different, so play around with them! Set cubicX=4 and cubicY=5 to get an ugly Arc.


I attempted to make align work with XY inputs but the AR calculations became a nightmare. I also attempted to let less then 3 out of 4 inputs being defined, and the code started to really suck.
mikeytown2 is offline   Reply With Quote
Old 25th July 2008, 03:01   #79  |  Link
NerdWithNoLife
Registered User
 
NerdWithNoLife's Avatar
 
Join Date: Jul 2007
Posts: 157
If possible, how would I use KenBurnsEffect/Zoombox to grow/shrink an image, (not just zoom it)? Enlarging an image without displacing it, if that makes sense.
__________________
f=33
NerdWithNoLife is offline   Reply With Quote
Old 25th July 2008, 09:51   #80  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
I think overlay would be the way to do it, here are 2 examples

Code:
r = BlankClip(120,color=$FF0000)
g = ColorBars(320,240).Trim(0,119).KenBurnsEffect(endZoomFactor=200)

Overlay(r,g,160,120).KenBurnsEffect(endZoomFactor=50,endFrame=119)



r = BlankClip(color=$FF0000)
g = ColorBars(320,240).Trim(0,119).KenBurnsEffect(endZoomFactor=200,startFrame=60)

last + Overlay(r,g,160,120).KenBurnsEffect(endZoomFactor=50,startFrame=120)
Let me know if its close to what your looking for.

Last edited by mikeytown2; 25th July 2008 at 10:01.
mikeytown2 is offline   Reply With Quote
Reply

Tags
anamorphic, crop, dar, pan and scan, resize

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:52.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.