ffmpeg:将图像缩放到 X Y 位置(zoompan)

ffmpeg: zoom image to positions X Y (zoompan)

我正在使用 ffmpeg 将图像缩放到特定点 (x, y)。

我希望该点是缩放的最终位置。 我现在使用的命令是:

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

我想要一个将图像缩放到点 (x=4000, y=1000) 的视频。

使用 ffmpeg 命令放大图像的自定义点:

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可用于获取原始图像尺寸

我创建了一个方便的脚本 image_to_video_zoom.sh 来创建缩放到图像的自定义点并控制缩放级别和视频持续时间的视频:

#!/bin/bash

INPUT=""
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 "" || -z "" ]]
then
  XP="50"
  YP="50"
else
  XP=$(bc <<< "100*/${OW}")
  YP=$(bc <<< "100*/${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

示例:

./image_to_video_zoom.sh image.JPG 3 6 1200 1800
  1. 3 - 最大缩放(倍)。默认 2.5.
  2. 6 - 持续时间(秒)。默认 5.
  3. 1200 - 要放大的 X 坐标(像素)。
  4. 1800 - 要放大的 Y 坐标(像素)。

结果:

脚本允许控制缩放级别、视频持续时间和放大点。如果未指定放大点,脚本将创建缩放到图像中心的视频。

根据宽高比 (16:9),生成的视频按比例缩放为高度 1080 或宽度 1920。

可以使用裁剪过滤器将宽度为 1920 且高度大于 1080 的视频裁剪为 1920x1080:

ffmpeg -i "$INPUT" -filter:v "crop=1920:1080" "$OUTPUT"