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 12th March 2008, 10:28   #1  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
KenBurnsEffect() - Zoom, Pan & Rotate Clip. New Version Released May 27th, 2009!

http://en.wikipedia.org/wiki/Ken_Burns_Effect
Code:
# KenBurnsEffect() - May 27th, 2009
#  Given a clip, zooms and pans clip with the Ken Burns Effect.
# 
# Requirements:
#  zoom.dll
#   http://forum.doom9.org/showthread.php?t=49429				-Original zoom thread
#   http://avisynth.org/warpenterprises/files/zoom_25_dll_20050122.zip		-Direct Download
#  CalcBox(), ZoomBoxIt()
#   http://forum.doom9.org/showthread.php?p=1111789#post1111789
# 
# Inputs:
#  clip c: input clip, needs to be RGB32() if useZoomBox = 0 or 1
# Optional Parameters:
## <Starting Position> ##
#  Mode 2 - Starting Alignment:
#   int startAlign: -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 - Starting Box:
#   float startX1: upper left x cord
#   float startY1: upper left y cord
#   float startX2: lower right x cord
#   float startY2: lower right y cord
#               3 or 4 out of 4 points must be defined when using Mode 1
#               when omitting a single point, it will calculate the missing value, with the Aspect Ratio in mind.
#  
#  float startZoomFactor: 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 startPanX: shift the clip x pixels. Value in source pixels. - left, + right
#  float startPanY: shift the clip x pixels. Value in source pixels. - up, + down
#  float startAngle: Rotate clip so many degrees. Positive is Clockwise.
## </Starting Position> ##
#
## <Ending Position> ##
#  Mode 2 - Ending Alignment:
#   int endAlign: -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 - Ending Box:
#   float endX1: upper left x cord
#   float endY1: upper left y cord
#   float endX2: lower right x cord
#   float endY2: lower right y cord
#               3 or 4 out of 4 points must be defined when using Mode 1
#               when omitting a single point, it will calculate the missing value, with the Aspect Ratio in mind.
#  
#  float endZoomFactor: 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 endPanX: shift the clip x pixels. Value in source pixels. - left, + right
#  float endPanY: shift the clip x pixels. Value in source pixels. - up, + down
#  float endAngle: Rotate clip so many degrees. Positive is Clockwise.
## </Ending Position> ##
#
#  int width: Output Width
#  int height: Output Height
#  int startFrame: starting frame of pan and zoom
#  int endFrame: ending frame of pan and zoom
#  bool KeepState: If using start/end Frame, it keeps the clip at the start & end zoom level. Default = true
#  string ResizeMethod: name of resize function. Default = BilinearResize
#  float SourceDAR: Display Aspect Ratio of the Source. If 0 then it uses the source aspect ratio.
#  float TargetDAR: Display Aspect Ratio of the Target. Useful for DVD's. If 0 then it uses the source aspect ratio.
#
#  int useZoomBox: 0 - Never, 1 - for static parts, 2 - for everything. default 2
#  float Speed: 1 is "normal". For high quality set to something like 0.25. For speed set to 5+. Relevant if useZoomBox=0 or 1.
#  int cubic: Type of zoom, pan & rotate.
#  int cubicX: Type of pan in the x direction.
#  int cubicY: Type of pan in the y direction.
#  int cubicA: Type of rotation.
#  int cubicZ: Type of zoom.
#  int color: Color of letterbox border. Default: $000000 (Black). Irrelevant if useZoomBox=0 or 1.
# 
# 
# Notes:
#  Clip should be deinterlaced for best visual quality.
#  Aspect ratio for output and box(x1,y1,x2,y2) should be the same, unless you want to distort the clip.
#  The aspect ratio for the 2 boxes as well as the output should to be the same.
#  Default behavior is to center clip by adding borders (Align=-5).
#  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 KenBurnsEffect(clip c, 
\ int "startAlign", float "startX1", float "startY1", float "startX2", float "startY2", float "startZoomFactor", float "startPanX", float "startPanY", float "startAngle",
\ int   "endAlign", float   "endX1", float   "endY1", float   "endX2", float   "endY2", float   "endZoomFactor", float   "endPanX", float   "endPanY", float   "endAngle",
\ int "width", int "height", int "StartFrame", int "EndFrame", bool "KeepState", string "ResizeMethod", float "SourcePAR", float "SourceDAR", float "TargetPAR", float "TargetDAR",
\ int "useZoomBox", float "speed", int "cubic", int "cubicX", int "cubicY", int "cubicA", int "cubicZ", int "color")

{
	#Set Defaults
	startAlign = Default(startAlign, -5)
	endAlign = Default(endAlign, -5)
	startZoomFactor = Default(startZoomFactor, 100.0)
	endZoomFactor = Default(endZoomFactor, 100.0)
	startPanX = Default(startPanX, 0.0)
	startPanY = Default(startPanY, 0.0)
	endPanX = Default(endPanX, 0.0)
	endPanY = Default(endPanY, 0.0)
	startAngle = Default(startAngle, 0.0)
	endAngle = Default(endAngle, 0.0)
	width = Default(width, c.width())
	height = Default(height, c.height())
	length = c.Framecount()-1
	StartFrame = Default(StartFrame, 0)
	EndFrame = Default(EndFrame, length)
	KeepState = Default(KeepState, True)
	ResizeMethod = Default(ResizeMethod, "BilinearResize")
	SourceAR = float(c.width())/float(c.height())
	TargetAR = float(width)/float(height)
	useZoomBox = Default(useZoomBox, 2)
	speed = Default(speed, 1)
	cubic = Default(cubic, 0)
	cubicX = Default(cubicX, cubic)
	cubicY = Default(cubicY, cubic)
	cubicZ = Default(cubicZ, cubic)
	cubicA = Default(cubicA, cubic)
	color = Default(color, $000000)
	
	#Calculate Defaults
	modzoom = Max(Float(c.width())/Float(width),Float(c.height())/Float(height))
	startZoomFactor = startZoomFactor<0 ? (abs(startZoomFactor)/100.0)*modzoom : (abs(startZoomFactor)/100.0)
	endZoomFactor = endZoomFactor<0 ? (abs(endZoomFactor)/100.0)*modzoom : (abs(endZoomFactor)/100.0)
	
	#Check For Any Unreasonable Inputs
	Assert(startZoomFactor<>0, "KenBurnsEffect: startZoomFactor can not be zero.")
	Assert(endZoomFactor<>0, "KenBurnsEffect: endZoomFactor can not be zero.")
	Assert((Defined(startX1) && Defined(startY1) && (Defined(startX2) || Defined(startY2))) || !(Defined(startX1) && Defined(startY1) && Defined(startX2) && Defined(startY2)), "KenBurnsEffect: when using Mode 1, you must define startX1,startY1, startX2 and/or startY2")
	Assert((Defined(endX1) && Defined(endY1) && (Defined(endX2) || Defined(endY2))) || !(Defined(endX1) && Defined(endY1) && Defined(endX2) && Defined(endY2)), "KenBurnsEffect: when using Mode 1, you must define endX1,endY1, endX2 and/or endY2")
	Assert(startAlign<9 || startAlign>-9, "KenBurnsEffect: startAlign [" + String(startAlign) + "] should be between -9 and 9.")
	Assert(endAlign<9 || endAlign>-9, "KenBurnsEffect: endAlign [" + String(endAlign) + "] should be between -9 and 9.")
	Assert(IsRGB32(c) || useZoomBox==2, "KenBurnsEffect: Clip Needs To Be RGB32. Use ConvertToRGB32() or set useZoomBox=2")
	Assert(!((cubic>0 || cubicX>0 || cubicY>0 || cubicZ>0 || cubicA>0) && useZoomBox==2), "KenBurnsEffect: Can not use the Cubic option when useZoomBox=2. Set useZoomBox to 0 or 1 or don't use cubic.")
	Assert(endFrame-startFrame<=length, "KenBurnsEffect: Transition length[" + String(endFrame-startFrame) + "] greater then clip lenght[" + String(length) + "]")
	Assert(startFrame<endFrame, "KenBurnsEffect: Starting Frame[" + String(startFrame) + "] greater then Ending Frame[" + String(endFrame) + "]")
	#Assert(useZoomBox == 0 && !(startAngle == 0), "KenBurnsEffect: You must set useZoomBox=0, if using startAngle [" + String(startAngle) + "]")
	#Assert(useZoomBox == 0 && !(endAngle == 0), "KenBurnsEffect: You must set useZoomBox=0, if using endAngle [" + String(endAngle) + "]")
	
	
	#Do Some Magic
	Eval (CalcBox(c, 2, width, height, TargetAR, SourceAR, startZoomFactor, startPanX, startPanY, startAlign, startX1, startY1, startX2, startY2, SourcePAR, SourceDAR, TargetPAR, TargetDAR))
	Eval (CalcBox(c, 3, width, height, TargetAR, SourceAR, endZoomFactor, endPanX, endPanY, endAlign, endX1, endY1, endX2, endY2, SourcePAR, SourceDAR, TargetPAR, TargetDAR))
	
	
	#Check For Any Unreasonable Inputs
	Assert(startX1<startX2, "KenBurnsEffect: Start X1[" + String(startX1) + "] point larger then Start X2 Point[" + String(startX2) + "]")
	Assert(startY1<startY2, "KenBurnsEffect: Start Y1[" + String(startY1) + "] point larger then Start Y2 Point[" + String(startY2) + "]")
	Assert(endX1<endX2, "KenBurnsEffect: End X1[" + String(endX1) + "] point larger then End X2 Point[" + String(endX2) + "]")
	Assert(endY1<endY2, "KenBurnsEffect: End Y1[" + String(endY1) + "] point larger then End Y2 Point[" + String(endY2) + "]")	

	
	#non pan frames 
	start = useZoomBox>0 && startFrame>0 ? KeepState ? c.Trim(0, -startFrame).ZoomBoxIt(width, height, ResizeMethod, startX1, startY1, startX2, startY2, color) : c.Trim(0, -startFrame) : nop()
	end = useZoomBox>0 && endFrame<length ? KeepState ? c.Trim(endFrame+1, 0).ZoomBoxIt(width, height, ResizeMethod, endX1, endY1, endX2, endY2, color) : c.Trim(endFrame+1, 0) : nop()
	#zoom and pan frames
	cAlt = c.Trim(startFrame, endFrame)
	cAlt = useZoomBox==2 ? Animate(0, cAlt.framecount()-1, "ZoomBoxIt", cAlt, width, height, ResizeMethod, Float(startX1),Float(startY1), Float(startX2),Float(startY2), color, cAlt, width, height, ResizeMethod, Float(endX1),Float(endY1),  Float(endX2),Float(endY2), color) :nop()

	
	#add in static frames
	cAlt = useZoomBox==2 && startFrame>0 ? start + cAlt : cAlt
	cAlt = useZoomBox==2 && endFrame<length ? cAlt + end : cAlt
	
	#get center of start rectangle from first box
	startCenterX = startX1+((startX2-startX1)/2.0)-0.5
	startCenterY = startY1+((startY2-startY1)/2.0)-0.5
	
	#get center of end rectangle from second box
	endCenterX = endX1+((endX2-endX1)/2.0)-0.5
	endCenterY = endY1+((endY2-endY1)/2.0)-0.5
	
	#Speed Logic pt 1 - Resize clip 
	width = Float(width)/speed
	height = Float(height)/speed	
	
	#get starting zoom factor from first box
	startZoomFactorX = width/float(startX2-startX1)
	startZoomFactorY = height/float(startY2-startY1)
	
	#get ending zoom factor from second box
	endZoomFactorX = width/float(endX2-endX1)
	endZoomFactorY = height/float(endY2-endY1)
	
	
	#Pan starting and ending x point
	srcxSE = SplineCalc(c, cubicX, startFrame, startCenterX, endFrame, endCenterX)
	
	#Pan starting and ending y point
	srcySE = SplineCalc(c, cubicY, startFrame, startCenterY, endFrame, endCenterY)
	
	#Zoom X
	factor_x_SE = SplineCalc(c, cubicZ, startFrame, startZoomFactorX, endFrame, endZoomFactorX)
	
	#Zoom Y
	factor_y_SE = SplineCalc(c, cubicZ, startFrame, startZoomFactorY, endFrame, endZoomFactorY)
	
	#Rotation
	angleSE = SplineCalc(c, cubicA, startFrame, startAngle, endFrame, endAngle)
	
	
	#non pan frames 
	start = useZoomBox==0 ? c.Zoom(srcx=String(startCenterX), srcy=String(startCenterY), factorx=String(startZoomFactorX), factory=String(startZoomFactorY), width=Round(width), height=Round(height), angle=String(startAngle)).Trim(0, -startFrame) : start
	end = useZoomBox==0   ? c.Zoom(srcx=String(endCenterX), srcy=String(endCenterY), factorx=String(endZoomFactorX), factory=String(endZoomFactorY), width=Round(width), height=Round(height), angle=String(endAngle)).Trim(endFrame+1, 0) : end
	
	#Do the zoom/pan
	c = useZoomBox<2 ? c.Zoom(srcx=srcxSE, srcy=srcySE, factorx=factor_x_SE, factory=factor_y_SE, width=Round(width), height=Round(height), angle=angleSE).Trim(startFrame, endFrame) : nop()
	
	#speed Logic pt 2 - Scale back up or down depending on speed set
	c = useZoomBox==1 ? Eval(ResizeMethod + "(c, " + String(Round(width*speed)) + ", " + String(Round(height*speed)) + ")" ) : c
		
	#Add in static frames
	c = useZoomBox<2 && startFrame>0 ? start + c : c
	c = useZoomBox<2 && endFrame<length ? c + end : c
	
	#speed Logic pt 2 - Scale back up or down depending on speed set
	c = useZoomBox==0 ? Eval(ResizeMethod + "(c, " + String(Round(width*speed)) + ", " + String(Round(height*speed)) + ")" ) : c
	useZoomBox==2 ? cAlt :c
}
KenBurnsEffect needs zoom.dll and ZoomBoxIt(), CalcBox() (next post).
Original zoom.dll Thread http://forum.doom9.org/showthread.php?t=49429
Details in Next Post (scroll down)

Last edited by mikeytown2; 28th May 2009 at 09:18.
mikeytown2 is offline   Reply With Quote
Old 13th March 2008, 06:33   #2  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
ZoomBox(), ZoomBoxIt(), CalcBox(), SplineCalc()
Code:
# ZoomBox() - June 12st, 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 ModAR: 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
#   float y1: upper left y cord
#   float x2: lower right x cord
#   float y2: lower right y cord
#               3 or 4 out of 4 points must be defined when using Mode 1
#               when omitting a single point, 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).
# 
# 
# Notes
#  Clip should be deinterlaced for best visual quality.
#  Aspect ratio for output and box(x1,y1,x2,y2) should be the same, unless you want to distort the clip.
#  Default behavor 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 controll the position of the zoomFactor.
#  Mode 1 (x1,y1,x2,y2) can take values from a crop opperation. 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 "SourcePAR", float "SourceDAR", float "TargetPAR", float "TargetDAR",
\ int "Align", float "x1", float "y1", float "x2", float "y2", float "zoomFactor", float "panX", float "panY", 
\ int "color")
{
	#Set Defaults
	width = Default(width, c.width())
	height = Default(height, c.height())
	ResizeMethod = Default(ResizeMethod, "BilinearResize")
	SourceAR = float(c.width())/float(c.height())
	TargetAR = float(width)/float(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)

	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((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.")
	
	#Do Some Magic
	Eval (CalcBox(c, 1, width, height, TargetAR, SourceAR, zoomFactor, panX, panY, Align, x1, y1, x2, y2, SourcePAR, SourceDAR, TargetPAR, TargetDAR))

	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) + "]")
	

	ZoomBoxIt(c, width, height, ResizeMethod, x1, y1, x2, y2, color)
}

Function ZoomBoxIt(clip c, int width, int height, string ResizeMethod, float x1, float y1, float x2, float y2, int color)
{
	#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)
	
	#Do it! Yes there are only 2 lines that directly act upon the clip.
	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) + ")")	
}

Function CalcBox(clip c, int mode, int width, int height, float TargetAR, float SourceAR, float zoomFactor, float panX, float panY, float Align, float "x1", float "y1", float "x2", float "y2", float "SourcePAR", float "SourceDAR", float "TargetPAR", float "TargetDAR")
{
	#PAR/DAR Calculations
	SourceDAR = Defined(SourcePAR) ?
		\ SourcePAR==0 ? SourceAR : SourcePAR*SourceAR
	\ : Defined(SourceDAR) ? 
		\ SourceDAR==0 ? SourceAR : Float(SourceDAR)
	\ : SourceAR
	TargetDAR =  Defined(TargetPAR) ?
		\ TargetPAR==0 ? TargetAR : TargetPAR*TargetAR
	\ : Defined(TargetDAR) ? 
		\ TargetDAR==0 ? TargetAR : Float(TargetDAR)
	\ : TargetAR
	
	#Calc ModAR
	ModAR = SourceDAR*TargetAR/TargetDAR
	
	
	#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 && ModAR==TargetAR ?
	\ "x1=0
	   x2=c.width()
	   y1=0
	   y2=c.height()"
	
	
	\ : (Align==-5 || Align==-4 || Align==-6) && ModAR>TargetAR ?
	\ "y1=0 - ((height*ModAR-width)/2.0)*(c.height()/Float(width))
	   y2=c.height() + ((height*ModAR-width)/2.0)*(c.height()/Float(width))
	   x1=0" + "
	   x2=c.width()"
	\ : (Align==5 || Align==2 || Align==8) && ModAR>TargetAR ?
	\ "x1=0 + ((height-width/ModAR)/2.0)*(c.width()/Float(height))
	   x2=c.width() - ((height-width/ModAR)/2.0)*(c.width()/Float(height))
	   y1=0
	   y2=c.height()" 
	\ : (Align==-5 || Align==-2 || Align==-8)  && ModAR<TargetAR ?
	\ "x1=0 - ((width/ModAR-height)/2.0)*(c.width()/Float(height))
	   x2=c.width() + ((width/ModAR-height)/2.0)*(c.width()/Float(height))
	   y1=0
	   y2=c.height()"
	\ : (Align==5 || Align==4 || Align==6)  && ModAR<TargetAR  ?
	\ "y1=0 + ((width-height*ModAR)/2.0)*(c.height()/Float(width))
	   y2=c.height() - ((width-height*ModAR)/2.0)*(c.height()/Float(width))
	   x1=0
	   x2=c.width()"
	
	
	\ : (Align==-1 || Align==-2 || Align==-3) && ModAR>TargetAR ?
	\ "y1=0
	   y2=c.height() + ((height*ModAR-width)/1.0)*(c.height()/Float(width))
	   x1=0
	   x2=c.width()"
	\ : (Align==-1 || Align==-4 || Align==-7)  && ModAR<TargetAR ?
	\ "x1=0
	   x2=c.width() + ((width/ModAR-height)/1.0)*(c.width()/Float(height))
	   y1=0
	   y2=c.height()"
	\ : (Align==-9 || Align==-8 || Align==-7) && ModAR>TargetAR ?
	\ "y1=0 - ((height*ModAR-width)/1.0)*(c.height()/Float(width))
	   y2=c.height()
	   x1=0
	   x2=c.width()"
	\ : (Align==-9 || Align==-6 || Align==-3)  && ModAR<TargetAR ?
	\ "x1=0 - ((width/ModAR-height)/1.0)*(c.width()/Float(height))
	   x2=c.width()
	   y1=0
	   y2=c.height()"
	
	
	\ : (Align==2 || Align==1 || Align==3) && ModAR<TargetAR  ?
	\ "y1=0
	   y2=c.height() - ((width-height*ModAR)/1.0)*(c.height()/Float(width))
	   x1=0
	   x2=c.width()" 
	\ : (Align==8 || Align==7 || Align==9) && ModAR<TargetAR  ?
	\ "y1=0 + ((width-height*ModAR)/1.0)*(c.height()/Float(width))
	   y2=c.height()
	   x1=0
	   x2=c.width()" 
	\ : (Align==4 || Align==1 || Align==7) && ModAR>TargetAR ?
	\ "x1=0
	   x2=c.width() - ((height-width/ModAR)/1.0)*(c.width()/Float(height))
	   y1=0
	   y2=c.height()" 
	\ : (Align==6 || Align==3 || Align==9) && ModAR>TargetAR ?
	\ "x1=0 + ((height-width/ModAR)/1.0)*(c.width()/Float(height))
	   x2=c.width()
	   y1=0
	   y2=c.height()"
	
	
	\ : ""
	Defined(x1) || Defined(y1) || Defined(x2) || Defined(y2) ? nop() : Eval(EvalString)

	#For non Align Input "Mode 1"
	x1tmp = Default(x1, 0)
	y1tmp = Default(y1, 0)
	x2tmp = Default(x2, c.width())
	y2tmp = Default(y2, c.height())
	
	#Take Crop Like Input
	x2tmp = x2tmp<=x1tmp && x2tmp<0 ? c.width() + x2tmp : x2tmp
	y2tmp = y2tmp<=y1tmp && y2tmp<0 ? c.height() + y2tmp : y2tmp
	
	#Set Optional parameters "Mode 1"
	test = 0
	test = Defined(x1) ? test+1 : test+0
	test = Defined(x2) ? test+1 : test+0
	test = Defined(y1) ? test+1 : test+0
	test = Defined(y2) ? test+1 : test+0
	Assert(test>=3, "ZoomBox/KenBurnsEffect: At least 3 out of 4 x1, y1, x2, y2 points must be defined; or do not set any")
	
	y2t = !Defined(y2) && Defined(y1) && Defined(x1) && Defined(x2) ? y1tmp + ((x2tmp-x1tmp)/TargetAR)/(SourceAR/ModAR) : y2tmp
	x2t = !Defined(x2) && Defined(x1) && Defined(y1) && Defined(y2) ? x1tmp + ((y2tmp-y1tmp)*TargetAR)*(SourceAR/ModAR) : x2tmp
	y1t = !Defined(y1) && Defined(y2) && Defined(x1) && Defined(x2) ? y2tmp - ((x2tmp-x1tmp)/TargetAR)/(SourceAR/ModAR) : y1tmp
	x1t = !Defined(x1) && Defined(x2) && Defined(y1) && Defined(y2) ? x2tmp - ((y2tmp-y1tmp)*TargetAR)*(SourceAR/ModAR) : x1tmp
	
	#Calc Pan Factor
	x1 = x1t-panX
	y1 = y1t-panY
	x2 = x2t-panX
	y2 = y2t-panY
	
	#Calc Zoom Factor
	CenterX = (x2-x1)/2.0
	CenterY = (y2-y1)/2.0
	CenterY = (Align<0 && ModAR>TargetAR)? CenterY*(TargetAR/ModAR): (Align>0 && ModAR<TargetAR)? CenterY*(TargetAR/ModAR): CenterY 
	CenterX = (Align>0 && ModAR>TargetAR)? CenterX/(TargetAR/ModAR): (Align<0 && ModAR<TargetAR)? CenterX/(TargetAR/ModAR): 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 ? 1.0/zoomFactor*CenterX+(x2-CenterX)/zoomFactor : x2
	y2 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY+((y2-CenterY)/(zoomFactor)) : (Align==3 || Align==2 || Align==1) && zoomFactor<>1 ? 1.0/zoomFactor*CenterY+(y2-CenterY)/zoomFactor : y2
	
	
	startString = "startX1=" + String(x1) + "
	startY1=" + String(y1) + "
	startX2=" + String(x2) + "
	startY2=" + String(y2) + ""
	
	endString = "endX1=" + String(x1) + "
	endY1=" + String(y1) + "
	endX2=" + String(x2) + "
	endY2=" + String(y2) + ""
	
	boxString = "x1=" + String(x1) + "
	y1=" + String(y1) + "
	x2=" + String(x2) + "
	y2=" + String(y2) + ""
	
	Return mode==1 ? boxString : mode==2 ? startString : mode==3 ? endString : ""
}


Function SplineCalc(clip c, int mode, int startFrame, float startF, int endFrame, float endF)
{
	splineString = mode==1 ?
	\ "spline(n, "
	\ + String(startFrame-1) + "," + String(startF) + ", "
	\ + String(startFrame) + "," + String(startF) + ", "
	\ + String(endFrame) + "," + String(endF) + ", "
	\ + String(endFrame+1) + "," + String(endF) + ", true)"
	
	\ : mode==2 ? "spline(n, "
	\ + String(startFrame) + "," + String(startF) + ", "
	\ + String(startFrame+(endFrame-startFrame)/3.0) + "," + String(startF) + ", "
	\ + String(endFrame-(endFrame-startFrame)/3.0) + "," + String(endF) + ", "
	\ + String(endFrame) + "," + String(endF) + ", true)"
	
	\ : mode==3 ? "spline(n, "
	\ + String(startFrame) + "," + String(startF) + ", "
	\ + String(startFrame+(endFrame-startFrame)/3.0) + "," + String(endF) + ", "
	\ + String(endFrame-(endFrame-startFrame)/3.0) + "," + String(startF) + ", "
	\ + String(endFrame) + "," + String(endF) + ", true)"
	
	\ : mode==4 ? "spline(n, "
	\ + String(startFrame) + "," + String(startF) + ", "
	\ + String((endFrame-startFrame)/2.0) + "," + String(startF) + ", "
	\ + String(endFrame) + "," + String(endF) + ", true)"
	
	\ : mode==5 ? "spline(n, "
	\ + String(startFrame) + "," + String(startF) + ", "
	\ + String((endFrame-startFrame)/2.0) + "," + String(endF) + ", "
	\ + String(endFrame) + "," + String(endF) + ", true)"
	
	\ : "spline(n, "
	\ + String(startFrame) + "," + String(startF) + ", "
	\ + String(endFrame) + "," + String(endF) + ", true)"
	Return splineString
}
Edits:
Dec 20th, 2009: Addedin missing function splinecalc
May 12th, 2008: Fixed some bugs. Will no longer auto correct width/height, resize will throw an error if its incorrect with the current color space.
May 13th, 2008: Quick Bug Fix with BoxAR.
May 15th, 2008: Can set OutputAR. Useful for clips that use DAR.
May 23rd, 2008: Fixed Most Aspect Ratio Errors. Use of 0,0,0,0 and -1,0,0,0 work correctly now. Finding the 4th point when given 3 isn't exact. Any help would be nice.
May 24th, 2008: All inputs optional. Input parameters reordered and changed. Should make usage easier. There are now no AR calculation errors! Thanks Gavion.
June 1st, 2008: Added Align, Pan(XY), zoomFactor. Split function up. Inputs are reordered!
June 3rd, 2008: Fixed DAR Float Bug.
June 6th, 2008: DisplayAR was incorrectly labeled, and is being replaced by SourceDAR and TargetDAR.
June 7th, 2008: Changed Pan(XY) to correctly act like it's supposed to in the documentation (negative is left or up).
June 12th, 2008: Added PAR. Any 3 out of 4 points can null, not just x2 or y2.

Example

Last edited by mikeytown2; 20th December 2009 at 20:06.
mikeytown2 is offline   Reply With Quote
Old 13th March 2008, 17:40   #3  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,375
Quote:
Originally Posted by mikeytown2 View Post
Code:
function KenBurnsEffect(string filename, int outWidth, int outHeight, int startPZFrame, int endPZFrame, int length, int startX1, int startY1, int startX2, int startY2, int endX1, int endY1, int endX2, int endY2, bool "fast", bool "qubic")
...
For some reason if you try to call the function with variable names in place it fails. filename="Stil\DSCN1091.JPG" fails.
That's because AviSynth only supports the 'named argument' syntax for 'optional' parameters (those names in quotes in the function definition).
Gavino is offline   Reply With Quote
Old 14th March 2008, 01:45   #4  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Ken Burns Effect Part 2

Future Ideas:
  • Add a cubic option(s) to allow a circle as a path.
  • Make Negative ZoomFactor work correctly in all cases.
This is a RFC (Request For Comments) any input is greatly appreciated!

Footnotes:
Older Concept Scripts
http://forum.doom9.org/showthread.php?t=47974
http://forum.doom9.org/showthread.php?t=32884
ZoomInFramesAnimate()

Here are some images i used for testing



This function is semi similar to:

Edit:
May 27th, 2009: added bool KeepState: If using start/end Frame, it keeps the clip at the start & end zoom level. Default = true
May 10th, 2008: Completely redid the speed logic. because zoom.dll's resize function is point resize, set speed to 0.25 for high quality results. The Cubic option now works at all times, and you can select it for x only or y only if wanted (will make an arc then). The use of ZoomBox for static parts is now optional, default: it doesn't use it. Fixed a minor bug with the total frame count. (Thanks Gavino). Fixed small error in the error code, now displays the correct info. Small change to the inputs of ZoomBox. Can now only use ZoomBox(). ZoomBox's sub pixel accuracy is set with the speed option here. subpixel = 1/speed.
May 11th, 2008: Fixed a simple, but semi major bug with useZoomBox.
May 12th, 2008: Small changes that take into account ZoomBox() changes. ResizeKAR() no longer needed. Fixed some bugs. Updated Example. Fixed a color space bug. Slight Speed Increase.
May 13th, 2008: Take Crop Like Input (negative x2 or y2). If (+-1 or 0),0,0,0 then assume clip is to be centered; -1 add borders, 0 or 1 zoom in.
May 15th, 2008: Can set OutputAR. Useful for clips that use DAR.
May 23rd, 2008: Fixed Most Aspect Ratio Errors. Use of 0,0,0,0 and -1,0,0,0 work correctly now. Finding the 4th point when given 3 isn't exact.
May 24th, 2008: No AR calculation errors! (thanks Gavino). Changed some internals so input into ZoomBox works.
June 1st, 2008: Added Align, Pan(XY), zoomFactor. Split function up. Inputs are reordered!
June 6th, 2008: DisplayAR was incorrectly labeled, and is being replaced by SourceDAR and TargetDAR.
June 7th, 2008: Added startAngle and endAngle. Can only be used when useZoomBox=0. Split off the spline code into its own function. Added cubicA to do cubic style angle rotations. Changed Pan(XY) to act correctly.
June 12th, 2008: Any 3 out of 4 points can null, not just x2 or y2. Cubic option is now an int with multiple presets (0-5 currently). Set CubicX different from CubicY for fun results! Reminder that Cubic can only be used when useZoomBox=0.


ZoomBox Examples
Resize 6 different sources (example, pictures) so they all fit in a single clip.
Code:
Width=640
Height=480
Resize="BlackmanResize"
Align=-5

a=ColorBars(320,480, "YV12").Trim(0,-1).ZoomBox(Width,Height,Resize, Align=Align)
b=ColorBars(480,480, "YV12").Trim(0,-1).ZoomBox(Width,Height,Resize, Align=Align)
c=ColorBars(640,480, "YV12").Trim(0,-1).ZoomBox(Width,Height,Resize, Align=Align)
d=ColorBars(720,480, "YV12").Trim(0,-1).ZoomBox(Width,Height,Resize, Align=Align)
e=ColorBars(854,480, "YV12").Trim(0,-1).ZoomBox(Width,Height,Resize, Align=Align)
f=ColorBars(960,480, "YV12").Trim(0,-1).ZoomBox(Width,Height,Resize, Align=Align)

a+b+c+d+e+f

Convert an anamorphic (16/9) DVD to square pixels
Code:
Width=854
Height=480
Resize="Lanczos4Resize"

MPEG2Source("AnamorphicDVD.d2v")
ZoomBox(Width,Height,Resize, SourceDAR=16.0/9.0)

Convert a square pixel source to anamorphic (16/9) DVD
Code:
Width=720
Height=480

ColorBars()
ZoomBox(Width, Height, TargetDAR=16.0/9.0)
Convert a anamorphic (16/9) DVD source to (4/3) DVD
Code:
Width=720
Height=480

MPEG2Source("AnamorphicDVD.d2v")
ZoomBox(Width, Height, SourceDAR=16.0/9.0, TargetDAR=4.0/3.0)

Convert DV Cam Pixels to Square Pixels
Code:
Width=640
Height=480
Align=5

ColorBars(720,480)
ZoomBox(Width, Height, SourcePAR=10.0/11.0, Align=Align)

Resize interlaced material, keeping the interlacing after resize.
Code:
AVISource("interlaced.avi")
AssumeTFF() #set order
bob()
ZoomBox(1280,720)
separatefields()
selectevery(4,0,3)
weave()
Replace bob() with your favorite bobber for higher quality results.


KenBurnsEffect Examples
Zoom out a clip 50%, move clip around the 4 corners of the screen, then zoom back to 100%.
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)

Pan a clip left to right, the right to left, then zoom out
Code:
Width=640
Height=480

a=ColorBars(2000,480).Trim(0,99)
a.KenBurnsEffect(StartAlign=4,EndAlign=6, Width=Width, Height=Height)
last+ a.KenBurnsEffect(StartAlign=6,EndAlign=4, Width=Width, Height=Height)
last+ a.KenBurnsEffect(StartAlign=4,EndAlign=-5, Width=Width, Height=Height)

KenBurnsEffect & ZoomBox AvsP Function Definitions
Go to your AvsP dir
Open up filterdb.dat with notepad
At the end of the file is a section called [USERFUNCTIONS]
Add this to the end of that section and save
Code:
KenBurnsEffect(
clip c,
int "startAlign"=-5 (-9 to 9),
float "startX1",
float "startY1",
float "startX2",
float "startY2",
float "startZoomFactor=100",
float "startPanX",
float "startPanY",
float "startAngle",
int "endAlign=-5 (-9 to 9)", 
float "endX1", 
float "endY1",
float "endX2",
float "endY2",
float "endZoomFactor=100",
float "endPanX",
float "endPanY",
float  "endAngle",
int "width",
int "height",
int "StartFrame",
int "EndFrame",
string "ResizeMethod"="BilinearResize" ("PointResize"/"BilinearResize"/"BilinearResize"/"LanczosResize"/"Lanczos4Resize"/"BlackmanResize"/"Spline16Resize"/"Spline36Resize"/"Spline64Resize"),
float "SourcePAR",
float "SourceDAR",
float "TargetPAR",
float "TargetDAR",
int "useZoomBox",
float "speed",
int "cubic",
int "cubicX",
int "cubicY",
int "cubicA",
int "cubicZ",
int "color"
)

ZoomBox(
clip c,
int "width",
int "height",
string "ResizeMethod"="BilinearResize" ("PointResize"/"BilinearResize"/"BilinearResize"/"LanczosResize"/"Lanczos4Resize"/"BlackmanResize"/"Spline16Resize"/"Spline36Resize"/"Spline64Resize"),
float "SourcePAR",
float "SourceDAR",
float "TargetPAR",
float "TargetDAR",
int "Align"=-5 (-9 to 9),
float "x1",
float "y1",
float "x2",
float "y2",
float "zoomFactor"=100,
float "panX",
float "panY", 
int "color"
)

Last edited by mikeytown2; 20th December 2009 at 20:06.
mikeytown2 is offline   Reply With Quote
Old 14th March 2008, 14:07   #5  |  Link
FlimsyFeet
Registered User
 
Join Date: Feb 2003
Posts: 362
So basically this function means you can make stuff like Microsoft's Photo Story 3 but witihin AviSynth?

That's a pretty neat function.
FlimsyFeet is offline   Reply With Quote
Old 14th March 2008, 20:47   #6  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Nice find with Photo Story 3, i gave it a spin, it has a fairly good gui; its also fast.

To answer your question, yes this does exactly that. To get the same transition effects that are in Photo Story 3 i would use TransAll. If your looking for more effects, take a peek at the wiki http://avisynth.org/mediawiki/External_filters#Effects.

Last edited by mikeytown2; 17th March 2008 at 02:12.
mikeytown2 is offline   Reply With Quote
Old 15th March 2008, 00:21   #7  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 365
In DVD slideshow GUI there is a simple gui for zoom.dll, with up to 20 keypoints, so if you want to play around with more keypoints and overshooting splines and afterwards take a look at the avisynth code - the animation/slideshow can be exported to .avs.

Btw. I think there is a FreeFrame plugin(which can be accessed with an avisynth plugin) which can do all the pos/rot/zoom stuff and it's very fast.
__________________
DVD slideshow GUI(Freeware).

Last edited by tin3tin; 15th March 2008 at 00:25.
tin3tin is offline   Reply With Quote
Old 15th March 2008, 02:11   #8  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
FreeFrame avisynth plugin
http://forum.doom9.org/showthread.php?threadid=92174
http://avisynth.org/warpenterprises/...l_20050426.zip

FreeFrame webpage
http://freeframe.sourceforge.net/

@tin3tin Thanks for making that sweet software, I took a look at the generated avs files. The only problem is the zoom values are hard coded in so it can be hard to use generally. Feel free to include my function into your software if you want. I'll be looking into FreeFrame. Do you have any examples where you use FreeFrame? Also do you have any other ideas on how i can improve this function?

Last edited by mikeytown2; 15th March 2008 at 02:40.
mikeytown2 is offline   Reply With Quote
Old 15th March 2008, 03:17   #9  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
I've been playing around briefly with FreeFrame, it is fast! I've maped out the behavior of PetePanSpinZoom.dll
Code:
# Freeframe
#  clip c
#  string dllname: dll location (full path)
#  bool showgui: show dll gui?
# dll paramaters:PetePanSpinZoom.dll - can take RGB32 or RGB24. 
#  float from 0 to 1: orgin in x cords: center 0.5. 1 puts video far right, 0 puts video far left
#  float from 0 to 1: orgin in y cords: center 0.5. 1 puts video on top, 0 puts video on bottom
#  float from 0 to 1: rotation: 0 = 0, 1 = 360.  0.5 = 180
#  float from 0 to 1: scale: normal 0.2. Zoom Range 0 = 0.3(in) to 1 = 4(out), when 0.2 = 1 is same.

ConvertToRGB32()
Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",true,0.5,0.5,0,0.2) #doesn't change picture, and shows gui

Last edited by mikeytown2; 15th March 2008 at 03:23. Reason: had a brief case of Dyslexia
mikeytown2 is offline   Reply With Quote
Old 15th March 2008, 07:34   #10  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Using the test2b.png file and this code I've tried to calibrate the input values.
Code:
KenBurnsEffecter("testP2.png", 640, 480, 10, 20, 30, 0, 0, 640, 480, 320, 240, 640, 480, true, false)

function KenBurnsEffecter(string filename, int outWidth, int outHeight, int startPZFrame, int endPZFrame, int length, int startX1, int startY1, int startX2, int startY2, int endX1, int endY1, int endX2, int endY2, bool "fast", bool "cubic")
{
	#set defaults
	fast = Default(fast, false)
	cubic = Default(cubic, false)
	
	#Check For Any Unreasonable Inputs
	Assert(startX1<startX2, "KenBurnsEffect: Start X1[" + String(startX1) + "] point larger then X2 Point[" + String(startX1) + "]")
	Assert(startY1<startY2, "KenBurnsEffect: Start Y1[" + String(startY1) + "] point larger then Y2 Point[" + String(startY1) + "]")
	Assert(endX1<endX2, "KenBurnsEffect: End X1[" + String(endX1) + "] point larger then X2 Point[" + String(endX1) + "]")
	Assert(endY1<endY2, "KenBurnsEffect: End Y1[" + String(endY1) + "] point larger then Y2 Point[" + String(endY1) + "]")
	Assert(startPZFrame<endPZFrame, "KenBurnsEffect: Starting Frame[" + String(startPZFrame) + "] greater then Ending Frame[" + String(endPZFrame) + "]")
	Assert(endPZFrame-startPZFrame<=length, "KenBurnsEffect: Transition length[" + String(endPZFrame-startPZFrame) + "] greater then clip lenght[" + String(length) + "]")
	Assert(Float(startX2-startX1)/Float(startY2-startY1) == Float(endX2-endX1)/Float(endY2-endY1), "Starting Aspect Ratio[" + String(Float(startX2-startX1)/Float(startY2-startY1)) + "] does not equal ending Aspect Ratio [" + string(Float(endX2-endX1)/Float(endY2-endY1)) + "]")
	Assert(Float(startX2-startX1)/Float(startY2-startY1) == Float(outWidth)/Float(outHeight), "Box Aspect Ratio[" + String(Float(startX2-startX1)/Float(startY2-startY1)) + "] does not equal clip output Aspect Ratio [" + string(Float(outWidth)/Float(outHeight)) + "]")
	
	#load image
	img = ImageSource(filename, start=0, end=length, fps=30).ConvertToRGB32()
	
	#fix aspect ratio
	ratioS = Float(img.width())/Float(img.height())
	ratioD = Float(outWidth)/Float(outHeight)
	BorderAddWidth = height(img)-Round(img.width()*ratioD/2)*2
	BorderAddHeight = width(img)-Round(img.height()/ratioD/2)*2
	
	img = (ratioS>ratioD) ? img.AddBorders(0, 0, 0, BorderAddWidth/4) : (ratioS<ratioD) ? img.AddBorders(0, 0, BorderAddHeight/4, 0) : img
	
	#get center of start rectangle
	startCenterX = startX1+((startX2-startX1)/2)-0.5
	startCenterY = startY1+((startY2-startY1)/2)-0.5
	
	#get center of end rectangle
	endCenterX = endX1+((endX2-endX1)/2)-0.5
	endCenterY = endY1+((endY2-endY1)/2)-0.5
	
	#get starting zoom factor
	startZoomFactor = (float(img.width())/float(startX2-startX1) + float(img.height())/float(startY2-startY1))/2
	
	#get ending zoom factor
	endZoomFactor = (float(img.width())/float(endX2-endX1) + float(img.height())/float(endY2-endY1))/2
	
	#Switch To Fast Mode
	startCenterX = fast ? startCenterX/(Float(img.width())/Float(outWidth)): startCenterX
	startCenterY = fast ? startCenterY/(Float(img.height())/Float(outHeight)): startCenterY
	endCenterX = fast ? endCenterX/(Float(img.width())/Float(outWidth)): endCenterX
	endCenterY = fast ? endCenterY/(Float(img.height())/Float(outHeight)): endCenterY
	img = fast ? Spline64Resize(img, outWidth, outHeight): img
		
	#Pan starting and ending x point
	srcx =   "spline(n, " + String(startPZFrame-1) + "," + String(startCenterX) + ", " + String(startPZFrame) + ", " + String(startCenterX) + ", " + String(endPZFrame) + "," + String(endCenterX) + ", " + String(endPZFrame+1) + "," + String(endCenterX) + ", " + String(cubic) + ")"
		
	#Pan starting and ending y point
	srcy =   "spline(n, " + String(startPZFrame-1) + "," + String(startCenterY) + ", " + String(startPZFrame) + "," + String(startCenterY) + ", " + String(endPZFrame) + "," + String(endCenterY) + ", " + String(endPZFrame+1) + "," + String(endCenterY) + ", " + String(cubic) + ")"

	#Zoom
	factor = "spline(n, " + String(startPZFrame-1) + "," + String(startZoomFactor) + ", " + String(startPZFrame) + "," + String(startZoomFactor) + ", " + String(endPZFrame) + "," + String(endZoomFactor) + ", " + String(endPZFrame+1) + "," + String(endZoomFactor) + ", " + String(cubic) + ")"
		
	#do it
	img.Zoom(srcx=srcx, srcy=srcy, factor=factor, show=true).Spline64Resize(outWidth, outHeight)
	#img = img.AddBorders(img.width()/2, img.height()/2, img.width()/2, img.height()/2)
	
	x = float(img.width())/float(startCenterX+0.5)/4
	y = float(startCenterY+0.5)/float(img.height())
	z = 5/startZoomFactor/25
	last + img.Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,x,y,0,z).Spline64Resize(outWidth, outHeight).Subtitle(" x:" + string(x) + "  y:" + string(y) + "  z:" + string(z))
	x = float(img.width())/float(endCenterX+0.5)/4
	y = float(endCenterY+0.5)/float(img.height())
	z = 5/endZoomFactor/25
	return last + img.Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,x,y,0,z).Spline64Resize(outWidth, outHeight).Subtitle("x: " + string(x) + "  y:" + string(y) + "  z:" + string(z))

}
This gets close, but to make the last 1/4 of the video correct
x value should be 0.000 instead of 1/3
y value should be 1.000 instead of 3/4
z value should be 1/15 instead of 1/10

Which maxes out the function for x & y. In order to zoom in more i would have to shift the picture. This gets ugly fast. I don't plan on pursuing this venture, but if someone wants to pick up where i left off, by all means continue. PetePanSpinZoom.dll seems to give higher quality results too.


Looks like if this is going to get faster, optimization of zoom.dll is needed.

Last edited by mikeytown2; 15th March 2008 at 07:44.
mikeytown2 is offline   Reply With Quote
Old 15th March 2008, 18:02   #11  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,375
Quote:
Originally Posted by mikeytown2 View Post
Looks like if this is going to get faster, optimization of zoom.dll is needed.
Have you considered using the width and height parameters of zoom?

With judicious use of these parameters, it ought to be possible to speed up your function a lot.

At the moment you are zooming the entire image (albeit a reduced one in fast mode), but often most of the pixels will get thrown away in the final result.

It might involve changing the logic of your script a fair bit, but it's worth looking into, if you haven't already.

(Not sure if your experiments with FreeFrame, etc, make my suggestion redundant, as I haven't caught up with that part of the discussion yet.)
Gavino is offline   Reply With Quote
Old 16th March 2008, 06:40   #12  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Quote:
Originally Posted by Gavino View Post
Have you considered using the width and height parameters of zoom?

With judicious use of these parameters, it ought to be possible to speed up your function a lot.

At the moment you are zooming the entire image (albeit a reduced one in fast mode), but often most of the pixels will get thrown away in the final result.

It might involve changing the logic of your script a fair bit, but it's worth looking into, if you haven't already.

(Not sure if your experiments with FreeFrame, etc, make my suggestion redundant, as I haven't caught up with that part of the discussion yet.)
I've taken a stab at using the other parameters of zoom(), and I've given up on it. I took your suggestion though and improved my other function ZoomBox() .


Here is a very BAD example of what the ZoomBox can do...
Code:
Global w=0 
Global x=0 
Global y=640
Global z=640
Global Resizer = "Spline16Resize"
Global zoomstep = -8

a = ImageSource("testP2.png", end=1, fps=30).ConvertToRGB32().ResizeKAR(640,640, Resizer).Trim(0,-1)

VeryBadIdea(a)
Global zoomstep = 8
last + VeryBadIdea(a)
Global zoomstep = 8
last + VeryBadIdea(a)

Function BadIdea(clip c)
{
	Global w = w+zoomstep
	Global x = x+zoomstep
	GLobal y = y-zoomstep
	Global z = z-zoomstep
	return c
}


Function VeryBadIdea(clip a)
{
	a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
	last + a.ZoomBox(w, x, y, z, Resizer=Resizer).ZoomBox(0, 80, 640, 560, 640, 480, Resizer=Resizer).Subtitle("  w: " + String(w) + "  x: " + String(x) + "  y: " + String(y) + "  z: " + String(z)).BadIdea()
}


# ZoomBox() - March 15th, 2008
#  Put a "box" around a clip. Box can be used to zoom in or out.
# 
# Cordinates for ZoomBox:
#  int x1: upper left x cord
#  int y1: upper left y cord
#  int x2: lower right x cord
#  int y2: lower right y cord
# Optional Parameters
#  int w: output width
#  int h: output height
#  string Resizer: name of resize function. Default = BilinearResize
# 
# Notes
#  Aspect ratio for output and box must be the same.
#  Be aware of colorspace resctictions.

Function ZoomBox(clip c, int x1, int y1, int x2, int y2, int "w", int "h", string "Resizer")
{
	#set defaults
	w = Default(w, c.width())
	h = Default(h, c.height())
	Resizer = Default(Resizer, "BilinearResize")
	
	#Check For Any Unreasonable Inputs
	Assert(x1<x2, "ZoomBox: Start x1[" + String(x1) + "] point larger then x2 Point[" + String(x2) + "]")
	Assert(y1<y2, "ZoomBox: Start y1[" + String(y1) + "] point larger then y2 Point[" + String(y2) + "]")
	Assert(Float(x2-x1)/Float(y2-y1) == Float(w)/Float(h), "ZoomBox: Box Aspect Ratio [" + String(Float(x2-x1)/Float(y2-y1)) + "] does not equal clip output Aspect Ratio [" + string(Float(w)/Float(h)) + "]")
	
	#inverse zoomfactor
	zx = float(w)/float(x2-x1)
	zy = float(h)/float(y2-y1)
	
	#shrinkpic before for speed boost when zooming out
	wOut = zx<1 ? zx*c.width() : c.width()
	x1 = zx<1 ? zx*x1 : x1
	x2 = zx<1 ? zx*x2 : x2
	hOut = zy<1 ? zy*c.height() : c.height()
	y1 = zy<1 ? zy*y1 : y1
	y2 = zy<1 ? zy*y2 : y2
	c = Eval(Resizer + "(c," + String(Round(wOut)) + "," + String(Round(hOut)) + ")")
	
	#Add Borders If Needed
	left = x1 < 0 ? -x1 : 0
	top = y1 < 0 ? -y1 : 0
	right =  x2-c.width() > 0 ? x2-c.width() : 0
	bottom =  y2-c.height() > 0 ? y2-c.height() : 0
	d = AddBorders(c, round(left), round(top), round(right), round(bottom))
	
	#Crop If Needed
	left = x1 > 0 ? x1 : 0
	top = y1 > 0 ? y1 : 0	
	right = x2-c.width() < 0 ?  x2-c.width() : 0
	bottom = y2-c.height() < 0 ? y2-c.height() : 0
	c = Crop(d, round(left), round(top), round(right), round(bottom))
	
	#Resize for output
	Return Eval(Resizer + "(c," + String(w) + "," + String(h) + ")")
}

function ResizeKAR(clip c, int maxW, int maxH, string "ResizeMethod", int "BackgroundColor")
{
	BackgroundColor = Default(BackgroundColor, $000000)
	ResizeMethod = Default(ResizeMethod, "BilinearResize")
	ratioS = Float(width(c))/Float(height(c))
	ratioD = Float(maxW)/Float(maxH)
	newW = Round(maxH*ratioS/2)*2
	newH = Round(maxW/ratioS/2)*2
	
	
	#Dest Higher Then Source; Dest Wider Then Source; Same Ratio
	c = 
	\	(ratioS>ratioD) ? 
	\	Eval(ResizeMethod + "(c, " + String(maxW) + ", " + String(newH) + ")").
	\	AddBorders(0, Round((maxH-newH)/2), 0, Round((maxH-newH)/2), BackgroundColor) :
	\	(ratioS<ratioD) ? 
	\	Eval(ResizeMethod + "(c, " + String(newW) + ", " + String(maxH) + ")").
	\	AddBorders(Round((maxW-newW)/2), 0, Round((maxW-newW)/2), 0, BackgroundColor) :
	\	(ratioS==ratioD) ?
	\	Eval(ResizeMethod + "(c, " + String(maxW) + ", " + String(maxH) + ")" ) :
	\	nop()
	
	#fix 1px changes, works only with 4:4:4
	c = 
	\	IsInterleaved(c) && (maxW>width(c)) ? c.AddBorders(0, 0, 1, 0) : 
	\	IsInterleaved(c) && (maxH>height(c)) ? c.AddBorders(0, 0, 0, 1) : 
	\	c
	return c
}
This code requires no DLL's. It is a good way to see how a resizer effects the picture in terms of ringing.

Last edited by mikeytown2; 16th March 2008 at 06:46.
mikeytown2 is offline   Reply With Quote
Old 17th March 2008, 13:39   #13  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
If anyone could explain why the picture likes to jump around when i use animate with zoombox, i would appreciate it. Or i guess i should ask why does this jump and zoom.dll not jump around? Any ideas on how i can fix it?

Code:
#SetMemoryMax(512)
#b = ImageSource("New Folder\testp2.png", end=99, fps=60)
b = colorbars().trim(0,99)

Animate(0, 99, "ZoomBoxer", b, 0.0, 0.0, 640.0, 480.0, 1, b, 320.0, 240.0, 640.0, 480.0, 1)
last + Animate(0, 99, "ZoomBoxer", b, 320.0, 240.0, 640.0, 480.0, 1, b, 416.0, 312.0, 480.0, 360.0, 1)
last + Animate(0, 99, "ZoomBoxer", b, 416.0, 312.0, 480.0, 360.0, 1, b, 0.0, 0.0, 640.0, 480.0, 1)
last + Animate(0, 99, "ZoomBoxer", b, 0.0, 0.0, 640.0, 480.0, 1, b, 288.0, 216.0, 352.0, 264.0, 1)

# ZoomBoxer() - March 17th, 2008
#  Put a "box" around a clip. Box can be used to zoom in or out.
# 
# Coordinates for ZoomBox:
#  float x1: upper left x cord
#  float y1: upper left y cord
#  float x2: lower right x cord
#  float y2: lower right y cord
# Optional Parameters
#  int IgnoreAR: 1 - Ignore Warnings; 0 - Show Warnings. Default=0, show warings
#  bool smooth: at the cost of speed (maybe quality) make zoom in's smoother. Default false
#  string Resizer: name of resize function. Default = BilinearResize
#  int w: output width
#  int h: output height
# 
# Notes
#  Aspect ratio for output and box must be the same.
#  Be aware of colors space restrictions.

Function ZoomBoxer(clip c, float x1, float y1, float x2, float y2, int "IgnoreAR", bool "smooth", string "Resizer", int "w", int "h")
{
	#set defaults
	w = Default(w, c.width())
	h = Default(h, c.height())
	Resizer = Default(Resizer, "BilinearResize")
	IgnoreAR = Default(IgnoreAR, 0)
	smooth = Default(smooth, false)
	wOut = c.width()
	hOut = c.height()
	
	#Check For Any Unreasonable Inputs
	Assert(x1<x2, "ZoomBox: Start x1[" + String(x1) + "] point larger then x2 Point[" + String(x2) + "]")
	Assert(y1<y2, "ZoomBox: Start y1[" + String(y1) + "] point larger then y2 Point[" + String(y2) + "]")
	Assert(IgnoreAR>0 || Float(x2-x1)/Float(y2-y1) == Float(w)/Float(h), "ZoomBox: Box Aspect Ratio [" + String(Float(x2-x1)/Float(y2-y1)) + "] does not equal clip output Aspect Ratio [" + string(Float(w)/Float(h)) + "]")
	
	#fix aspect ratio
	y3 = c.height()*(x2-x1)/Float(c.width())
	x3 = c.width()*(y2-y1)/Float(c.height())
	#x2=x3
	#y2=y3	
			
	#inverse zoomfactor, used to shrink or grow clip if needed
	zx = float(w)/float(x2-x1)
	zy = float(h)/float(y2-y1)
	#smoothA = smooth && zx>1 && zy>1 ? false : true
	#smooth = smooth ? smoothA : false

	#Shrink clip before for speed boost when zooming out, or blow up for smoother pic when zooming in.
	wOut = smooth || zx<1 ? zx*wOut : wOut
	x1 = smooth || zx<1 ? zx*x1 : x1
	x2 = smooth || zx<1 ? zx*x2 : x2
	hOut = smooth || zy<1 ? zy*hOut : hOut
	y1 = smooth || zy<1 ? zy*y1 : y1
	y2 = smooth || zy<1 ? zy*y2 : y2
	
	#Check ColorSpace
	x1 = c.IsYV12() || c.IsYUY2() ? Round(x1/2)*2 : x1
	x2 = c.IsYV12() || c.IsYUY2() ? Round(x2/2)*2 : x2
	y1 = c.IsYV12() || c.IsYUY2() ? Round(y1/2)*2 : y1
	y2 = c.IsYV12() || c.IsYUY2() ? Round(y2/2)*2 : y2
	wOut = c.IsYV12() || c.IsYUY2() ? Round(wOut/2)*2 : wOut
	hOut = c.IsYV12() || c.IsYUY2() ? Round(hOut/2)*2 : hOut
	
	#resize clip if needed
	c = Eval(Resizer + "(c," + String(Int(wOut)) + "," + String(Int(hOut)) + ")")
	
	#Add Borders If Needed
	left = x1<0 ? -x1 : 0
	top = y1<0 ? -y1 : 0
	right =  x2-c.width()>0 ? x2-c.width() : 0
	bottom =  y2-c.height()>0 ? y2-c.height() : 0
	d = AddBorders(c, Int(left)+8, Int(top)+8, Int(right)+8, Int(bottom)+8)
	
	#Crop If Needed
	left = x1 > 0 ? x1 : 0
	top = y1 > 0 ? y1 : 0	
	right = x2-c.width() < 0 ?  x2-c.width() : 0
	bottom = y2-c.height() < 0 ? y2-c.height() : 0
	
	d = Crop(d, Int(left)+8, Int(top)+8, Int(right)-8, Int(bottom)-8)
	#Resize for output
	Return Eval(Resizer + "(d," + String(w) + "," + String(h) + ")")#+ ",src_left=" + String(Int(left)+8) + ",src_top=" + String(Int(top)+8) + ",src_width=" + String(c.width() + right) + ",src_height=" + String(c.height() + bottom) + ")")
}
mikeytown2 is offline   Reply With Quote
Old 21st March 2008, 12:40   #14  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Function and example updated. Parameter order changed.

Given up on making a function to replace zoom.dll - too much work and the ability to select your own resize function not worth the effort. I do have a nice zoombox() function though.
mikeytown2 is offline   Reply With Quote
Old 9th May 2008, 05:07   #15  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Updated KenBurnsEffect() and ZoomBox()

KenBurnsEffect() Changes:
  • You only have to know 3 out of the 4 points for the 2 boxes. Can omit X2 or Y2 but not both. Set X2 to X1, or Y2 to Y1, in order for this to auto calc the appropriate missing point, while keeping the Output Aspect Ratio in mind. (Very Helpful)
  • Changed some variable names.
  • Fixed a Bug in the ZoomY if x and y zooms where different.
  • Speed Boost!

ZoomBox() Changes:
  • Located Here
  • Use of ResizeKAR makes this behave much better when it is Animated.

With these changes, KenBurnsEffect() is semi usable, before it was very hard because of all the aspect ratio calculations.
mikeytown2 is offline   Reply With Quote
Old 10th May 2008, 10:03   #16  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Updated KenBurnsEffect()

KenBurnsEffect() Changes:
  • Speed Logic Redone
  • Cubic option works for any situation.
  • Added a CubicX and CubicY options so the fast, slow, fast will only occur on that axis is desired. (useful for drawing a arc)
  • Use of ZoomBox in static parts optional.
  • Reordered inputs and made the start and end frames optional.
mikeytown2 is offline   Reply With Quote
Old 10th May 2008, 10:32   #17  |  Link
Dreassica
Registered User
 
Join Date: May 2002
Posts: 386
Would it be possible to use one of these functions to recreate a screwed up sidewards pan using a single panoramic created picture?
Dreassica is offline   Reply With Quote
Old 10th May 2008, 10:46   #18  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Quote:
Originally Posted by Dreassica View Post
Would it be possible to use one of these functions to recreate a screwed up sidewards pan using a single panoramic created picture?
by "screwed up" do you mean it is rotated, something like this?
http://en.wikipedia.org/wiki/Dutch_angle

The sidewards pan (I'm assuming something like left to right) is very doable! use KenBurnsEffect() and load the image into a clip. If you describe the desired movement (drawings always help), i can show you how to use this. The dimensions of the panoramic will be needed.

As a side note, did you use hugin to make the panoramic?
mikeytown2 is offline   Reply With Quote
Old 10th May 2008, 16:45   #19  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,375
Nice work, mikeytown. I was having a few problems with the version you posted on 8th May, but this latest one works pretty well.

Still, one bug remains - the output clip is missing the last frame of the panned region.

Fix:
Code:
#Do the zoom/pan
c = c.Zoom(srcx=srcxSE, srcy=srcySE, factorx=factor_x_SE, factory=factor_y_SE, width=Round(outWidth), height=Round(outHeight)).Trim(startPZFrame, endPZFrame-1)
- Replace endPZFrame-1 by endPZFrame in Trim
Gavino is offline   Reply With Quote
Old 10th May 2008, 19:51   #20  |  Link
Dreassica
Registered User
 
Join Date: May 2002
Posts: 386
Quote:
Originally Posted by mikeytown2 View Post
by "screwed up" do you mean it is rotated, something like this?
http://en.wikipedia.org/wiki/Dutch_angle

The sidewards pan (I'm assuming something like left to right) is very doable! use KenBurnsEffect() and load the image into a clip. If you describe the desired movement (drawings always help), i can show you how to use this. The dimensions of the panoramic will be needed.

As a side note, did you use hugin to make the panoramic?

No as in it cant be properly ivtced/fieldmatched as it has shit frames etc. I just selected a few good frames, used photoshop to append them to a panoramic view picture. Successfully did one such frame the manual way using allot of croppings to 640x480 shifting an x number of pixels. Just too timeconsuming, and I thought maybe this scripts could do it much faster and easier.
Dreassica 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:05.


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