I'm using ffmpeg to zoom an image to a specific point (x, y).
I want the point to be the final position of the zoom. The command I use now is:
ffmpeg -y -i zoomInimg.jpg -vf "scale=6198:2350:-1,zoompan=z='min(max(zoom,pzoom)+0.06,10)':d=2400:x=4000 :y=1000 :s=6198x2350" -t 5 zoomIn.mp4
I want to have a video of zooming an image to the point (x=4000, y=1000).
The ffmpeg
command to use zoom in to a custom point of an image:
ffmpeg -i "$INPUT" \
-vf "zoompan=z='min(zoom+${ZOOM_SPEED},${MAX_ZOOM})':x='iw/2-iw*(1/2-${XP}/100)*on/${DURATION}-iw/zoom/2':y='ih/2-ih*(1/2-${YP}/100)*on/${DURATION}-ih/zoom/2':d=${DURATION}:fps=${FPS}:s=${W}x${H}" \
-c:v libx264 "$OUTPUT" -y
ffprobe
can be used to get the original image dimension.
I created a convenient script image_to_video_zoom.sh
to create a video of zooming to a custom point of an image and controlling a zoom level and duration of the video:
#!/bin/bash
INPUT="$1"
OUTPUT="${INPUT%%.*}_zoom.MP4"
MAX_ZOOM="${2:-2.5}"
DURATION_SECONDS="${3:-5}"
FPS="30"
DURATION=$(bc <<< "${DURATION_SECONDS}*${FPS}")
ZOOM_SPEED=$(bc <<< "scale=4;(${MAX_ZOOM}-1)/${DURATION}")
SIZE=$(ffprobe -v error -select_streams v -show_entries stream=width,height -of csv=p=0:s=x "$INPUT")
OW=$(echo $SIZE | cut -d'x' -f1)
OH=$(echo $SIZE | cut -d'x' -f2)
if (( $(bc -l <<< "scale=4;${OW}/${OH} >= 16/9") ))
then
R=$(bc <<< "scale=4;${OH}/1080")
W=$(bc <<< "${OW}/${R}")
H=$(bc <<< "${OH}/${R}")
else
R=$(bc <<< "scale=4;${OW}/1920")
W=$(bc <<< "${OW}/${R}")
H=$(bc <<< "${OH}/${R}")
if (( $(bc <<< "${H}%2") ))
then
H=$(bc <<< "${H}-1")
fi
fi
if [[ -z "$4" || -z "$5" ]]
then
XP="50"
YP="50"
else
XP=$(bc <<< "100*${4}/${OW}")
YP=$(bc <<< "100*${5}/${OH}")
fi
ffmpeg -i "$INPUT" \
-vf "zoompan=z='min(zoom+${ZOOM_SPEED},${MAX_ZOOM})':x='iw/2-iw*(1/2-${XP}/100)*on/${DURATION}-iw/zoom/2':y='ih/2-ih*(1/2-${YP}/100)*on/${DURATION}-ih/zoom/2':d=${DURATION}:fps=${FPS}:s=${W}x${H}" \
-c:v libx264 "$OUTPUT" -y
Example:
./image_to_video_zoom.sh image.JPG 3 6 1200 1800
3
- max zoom (times). Default 2.5.6
- duration (seconds). Default 5.1200
- X coordinate (pixels) to zoom in.1800
- Y coordinate (pixels) to zoom in.The result:
The script allows controlling the zoom level, duration of the video and point to zoom in. If a point to zoom in is not specified, the script will create a video of zooming to the center of the image.
The resulting video is proportionally scaled to have height 1080 or width 1920 depending on the aspect ratio (16:9).
Video with width 1920 and height greater than 1080 can be cropped to 1920x1080 using crop filter:
ffmpeg -i "$INPUT" -filter:v "crop=1920:1080" "$OUTPUT"