View Full Version : Zooming with Avisynth Help
XBlade
18th July 2013, 08:45
Hello folks. I am sorry to bother with such a seemingly minor thing, but my skill with Avisynth is not so good, heh. I can't figure out how to Zoom with Avisynth smoothly.
Let's say I have a 1280x720 image. How would I be able to zoom in smoothly to let's say about 100 pixels down from directly in the center?
I have tried using Animate, but the zooming is very rough. I also have installed the Zoom plugin, however, I don't understand how to use that. I looked at the creators thread for Zoom here, but I just don't understand it at all :confused:
I just don't know what to do to get a smooth zoom effect... Any help will be appreciated.
Corpsecreate
18th July 2013, 09:36
I'm not sure if this is what your looking for but I quickly made this function:
function magnify(Clip clp, int x1, int y1, int x2, int y2, float magnification)
{
portion = clp.Crop(x1, y1, -(clp.width-x2), -(clp.height-y2))
return portion.Spline64Resize(portion.width*magnification, portion.height*magnification)
}
x1,y1 is the top left corner you want to magnify, x2,y2 is the bottom right corner.
Example of what it does:
http://img832.imageshack.us/img832/6730/s371.jpg
magnify(154,114,264,166,6)
http://img46.imageshack.us/img46/5759/fo8s.jpg
EDIT: After reading your question properly I can see you want to slowly zoom in and not just magnify a specific segment. I'll leave this up here just incase you like it anyway :P
StainlessS
18th July 2013, 12:46
http://avisynth.nl/index.php/Animate
To do a smoothly varying zoom, you would need to take into account the number of frames.
If you are zooming by eg 20 pixels per frame, it would not be smooth, to do it smoothly would
require doing it over sufficient number of frames and that may make it tediously slow.
Choose your poison.
Gavino
18th July 2013, 13:53
If you are zooming by eg 20 pixels per frame, it would not be smooth ...
Also, it's important to have a uniform rate of zooming.
If you are using the normal method of Animate'ing a resizer, be sure to pass floating-point values for the src_left, src_top, src_width and src_height arguments. For example, use 60.0 rather than 60.
Gavino
18th July 2013, 14:09
## example 1: zoom 1x to 5x
return Animate(C, 150, 180, "UUZoom", 1.0, 5.0)
...
function UUZoom(clip C, float factor, float pan, float tilt)
...
function UUSize2(clip C, int wid, int hgt, float pan, float tilt)
...
You need to enclose the names factor, pan and tilt in quotes in the function definitions to make them optional.
raffriff42
18th July 2013, 14:17
Thank you Gavino, I had temporarily unquoted them. I withdrew the script because it is not zooming smoothly. How does one pass floating-point values to XXXResize? I get an error.
EDIT - here's the script in its current state. Slow zoom looks terrible. Maybe it's the mod-2 border trimming, will check...
EDIT - try it now, it looks much better. A little unsteadiness remains. RGB32 source is required.
Zooms with pan & tilt. Pan & tilt are a little rough but good enough to zoom in on a desired focal point.
C=C.ConvertToRGB32(matrix="PC.709", chromaresample="spline36")
## zoom 1x to 5x
return Animate(C, 1, 280, "UUZoom", 1.0, 2.0)
return Animate(C,
\ 1,
\ 280,
\ "UUZoom",
\ 1.0, 0, 0,
\ 5.0, 0, 0)
/*
## zoom 3x, pan top-left to bottom-right
return Animate(C,
\ 150,
\ 180,
\ "UUZoom",
\ 3.0, -1.0, -1.0,
\ 3.0, 1.0, 1.0)
*/
/*
## zoom 1x, pan top-left to bottom-right (no effect)
return Animate(C,
\ 150,
\ 180,
\ "UUZoom",
\ 1.0, -1.0, -1.0,
\ 1.0, 1.0, 1.0)
*/
/*
## zoom 0.25x to 1.0, pan from top-left (motion needs refining)
return Animate(C,
\ 150,
\ 180,
\ "UUZoom",
\ 0.25, -1.0, -1.0,
\ 1.0, 1.0, 1.0)
*/
###############################
### zoom in on an image
#
#@param factor - range = 0.01 to 100 [default = 1.0]
#@param pan - range = -1.0 to +1.0: -1.0=left, 0.0=center, +1.0=right; [default = 0.0]
#@param tilt - range = -1.0 to +1.0: -1.0=up, 0.0=center, +1.0=down; [default = 0.0]
#
function UUZoom(clip C, float factor, float "pan", float "tilt")
{
Assert(C.IsRGB32, "UUZoom: clip must be RGB32")
factor = Default(factor, 1.0)
factor = (factor >= 0.01) ? factor : 0.01
factor = (factor < 100.0) ? factor : 100.0
inWid = C.Width
inHgt = C.Height
newWid = Round(factor * Float(inWid))
newHgt = Round(factor * Float(inHgt))
/*
dbgText = "c.Width = " + String(c.Width) + Chr(9) +
\ "c.Height = " + String(c.Height) + Chr(13) +
\ "newWid = " + String(newWid) + Chr(9) +
\ "newHgt = " + String(newHgt) + Chr(13) +
\ "factor = " + String(factor) + Chr(13) +
\ ""
return MessageClip(dbgText, width=640, shrink=false)
*/
C = C.Spline36Resize(newWid, newHgt)
C = C.UUSize2(inWid, inHgt, pan, tilt)
return C
}
##################################
### crop or add border to ensure clip is a certain size
#
#@param pan - range = -1.0 to +1.0: -1.0=left, 0.0=center, +1.0=right; [default = 0.0]
#@param tilt - range = -1.0 to +1.0: -1.0=up, 0.0=center, +1.0=down; [default = 0.0]
#
function UUSize2(clip C, int wid, int hgt, float "pan", float "tilt")
{
Assert(C.IsRGB32, "UUSize2: clip must be RGB32")
bdrWid = (wid - C.Width)
bdrHgt = (hgt - C.Height)
xctr = Default(pan, 0.0)
xctr = (xctr <= 1.0) ? xctr : 1.0
xctr = (xctr >= -1.0) ? xctr : -1.0
yctr = Default(tilt, 0.0)
yctr = (yctr <= 1.0) ? yctr : 1.0
yctr = (yctr >= -1.0) ? yctr : -1.0
bdrLt = Abs(Round(Float(bdrWid) / 2.0))
bdrLt = bdrLt + Round(bdrLt * xctr)
bdrLt = Sign(bdrWid) * bdrLt
bdrTp = Abs(Round(Float(bdrHgt) / 2.0))
bdrTp = bdrTp + Round(bdrTp * yctr)
bdrTp = Sign(bdrHgt) * bdrTp
bdrRt = (bdrWid - bdrLt)
bdrBt = (bdrHgt - bdrTp)
C = C.AddBorders(
\ ((bdrLt > 0) ? bdrLt : 0),
\ ((bdrTp > 0) ? bdrTp : 0),
\ ((bdrRt > 0) ? bdrRt : 0),
\ ((bdrBt > 0) ? bdrBt : 0))
C = C.Crop(
\ ((bdrLt < 0) ? -bdrLt : 0),
\ ((bdrTp < 0) ? -bdrTp : 0),
\ ((bdrRt < 0) ? bdrRt : wid),
\ ((bdrBt < 0) ? bdrBt : hgt))
return C
}
Gavino
18th July 2013, 14:31
How does one pass floating-point values to XXXResize? I get an error.
You use the src_left, src_top, src_width and src_height parameters - see http://avisynth.nl/index.php/Resize.
Normally when zooming, you Animate a resizer, resizing a clip to keep its original size while varying these parameters to select a smoothly changing source region from the frame.
raffriff42
18th July 2013, 14:41
Thank you again! (what, read the manual?) I must run run now so I'll fix this later, if someone hasn't posted something better in the meantime.
2Bdecided
18th July 2013, 14:43
While quite possible in AVIsynth, this is the kind of stuff better done in a decent NLE or effects program. Assuming you want to do this a lot while retaining your sanity.
Cheers,
David.
Gavino
18th July 2013, 15:47
While quite possible in AVIsynth, this is the kind of stuff better done in a decent NLE or effects program. Assuming you want to do this a lot while retaining your sanity.
You can retain your sanity by wrapping up the grisly details inside a generic function which can be reused.
For an example, see mikeytown2's KenBurnsEffect (http://forum.doom9.org/showthread.php?t=135776)().
I myself use something similar which I developed to suit my own requirements.
johnmeyer
18th July 2013, 17:28
While quite possible in AVIsynth, this is the kind of stuff better done in a decent NLE or effects program. Assuming you want to do this a lot while retaining your sanity.I agree with this. Use the right tool for the job. AVISynth is a great tool for video manipulations that require programatically inspecting the content of the video and then doing something clever with the information found in all those pixels. While you can do simple cropping and re-sizing as part of a script, doing a smooth zoom is something that just screams for an interactive GUI that is much better provided by your favorite NLE.
ARDA
18th July 2013, 19:21
Maybe this can help, function ZoomInOut by Didée
forum.doom9.org/showthread.php?p=1586571#post1586571
raffriff42
18th July 2013, 19:52
johnmeyer, you are right of course :) KenBurnsEffect() looks like it would fill the need perfectly anyway.
EDIT for basic zooms, I found it easier to call ZoomBox (http://forum.doom9.org/showthread.php?p=1111789#post1111789) (support function for KenBurnsEffect)
StainlessS
19th July 2013, 15:42
Raffriff42,
Just a tip (Gavino originated)
factor = Float(Default(factor, 1.0)) # use this instead of
factor = Default(factor, 1.0) # this
ensures that factor is a float if passed as int.
raffriff42
19th July 2013, 23:02
> ensures that factor is a float if passed as int
Ah, of course. Thank you StainlessS.
I'll go ahead and post a working (if hackish) script with examples C=C.ConvertToRGB32() ## RGB32 required
/*
*/
## zoom 1x to 2x
return Animate(C, 1, 280, "SimpleZoomBox",
\ 1.0, 0, 0,
\ 2.0, 0, 0)
/*
## zoom in, panning up and to the right
endzoom = 2.0 ## try different values here
return Animate(C, 1, 280, "SimpleZoomBox",
\ 1.0, 0, 0,
\ endzoom, (endzoom * 0.25), (endzoom * -0.6))
*/
/*
## (random BG video)
B = C.Levels(0, 0.7, 255, 32, 96)
\ .Subtitle("SIMPLE ZOOM", size=156, align=2, text_color=$00ffff)
## zoom out, ending up in top right corner over BG video
C = Animate(C,
\ 1, 280, "SimpleZoomBox",
\ 1.0, 0, 0,
\ 0.25, -0.5, 0.6)
return B.Overlay(C, Mask=C.ShowAlpha)
*/
/*
## pan and tilt at constant zoom factor
endzoom = 2.2 ## try different values here
offsetX = 0.98 * endzoom * (1.0 - (1.0 / endZoom)) ## 0.98 = large movement (1.00 = full)
offsetY = 0.33 * endzoom * (1.0 - (1.0 / endZoom)) ## 0.33 = small movement
return Animate(C,
\ 1, 280, "SimpleZoomBox",
\ endzoom, -offsetX, offsetY,
\ endzoom, offsetX, -offsetY)
*/
###############################
### zoom an image with pan & tilt;
### wraps call to ZoomBox with fewer arguments for easier animation
#
#@param factor - range = 0.01 to 100 [default = 1.0]
#@param pan - location in source which will be centered in target:
# < 0.0=left, 0.0=center, > 0.0=right [default = 0.0]
#@param tilt - location in source which will be centered in target:
# < 0.0=up, 0.0=center, > 0.0=down [default = 0.0]
#
function SimpleZoomBox(clip C, float factor, float "pan", float "tilt")
{
Assert(C.IsRGB32, "SimpleZoomBox: clip must be RGB32")
factor = Min(Max(0.01, Float(Default(factor, 1.0))), 100.0)
pan = Float(Default(pan, 0.0))
tilt = Float(Default(tilt, 0.0))
offsetX = -(0.5 * pan * Float(C.Width))
offsetY = -(0.5 * tilt * Float(C.Height))
C = C.ZoomBox(
\ zoomFactor=(factor * 100.0),
\ ResizeMethod="Spline16Resize",
\ panX=offsetX, panY=offsetY)
return C
}
XBlade
21st July 2013, 09:02
Um... I am sorry to say, but I don't really understand what you guys are talking about. :(
raffriff42
21st July 2013, 13:03
XBlade, this was your question:
>Let's say I have a 1280x720 image. How would I be able to zoom in smoothly to let's say about 100 pixels down from directly in the center?
C=Avisource(<path>).ConvertToRGB32()
return Animate(C, 1, 280, "SimpleZoomBox",
\ 1.0, 0, 0,
\ 5.0, 0, 0) "1, 280" means start zooming at frame 1 and complete the zoom by frame 280.
"1.0" means start at normal size (1x).
"5.0" means zoom to 5x.
"0, 0" means zoom in to the center of the image.
See example above ("zoom in, panning up and to the right") for zooming in to a particular spot.
For this to work, you need to copy the code for SimpleZoomBox from my post above; copy Zoombox and its helpers from here (http://forum.doom9.org/showthread.php?p=1111789#post1111789); then save as plain text to your Avisynth Plugins folder as Zoombox.avsi.
XBlade
22nd July 2013, 06:38
"1, 280" means start zooming at frame 1 and complete the zoom by frame 280.
"1.0" means start at normal size (1x).
"5.0" means zoom to 5x.
"0, 0" means zoom in to the center of the image.
See example above ("zoom in, panning up and to the right") for zooming in to a particular spot.
For this to work, you need to copy the code for SimpleZoomBox from my post above; copy Zoombox and its helpers from here (http://forum.doom9.org/showthread.php?p=1111789#post1111789); then save as plain text to your Avisynth Plugins folder as Zoombox.avsi.
Thanks for explaining what each of the commands mean.
Now, I should paste your code, and the code for Zoombox into a single text file and save that as .avsi? And that code you just posted will suffice for calling the effect?
raffriff42
22nd July 2013, 08:17
Yep! Functions *can* be placed directly in the .avs script, but functions that you want to call from many .avs scripts should be put into .avsi files in the Plugins folder.
Plugin autoload and name precedence (http://avisynth.nl/index.php/Plugins#Plugin_autoload_and_name_precedence_v2) (Avisynth wiki)
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.