View Single Post
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