如何在基于FFmpeg的Python图像对比视频生成脚本中实现平滑移动的滑块线条效果
如何在基于FFmpeg的Python图像对比视频生成脚本中实现平滑移动的滑块线条效果
你现在的脚本已经能生成基础的图像对比视频,但线性的滑块移动肯定会显得有点生硬,没法达到imgsli那种像人手自然拖拽的顺滑感对吧?别担心,咱们只需要修改FFmpeg滤镜里的表达式,给滑块的移动加上缓动效果,就能完美复刻那种自然的滑动感。
问题根源:原来的线性移动太生硬
你之前用的blend滤镜表达式是if(gte(X,W*T/{duration}),A,B),这里的T/{duration}是线性变化的,滑块会匀速从左到右移动,完全没有人手拖拽时“慢启动-加速-慢停止”的自然节奏。
解决方案:给滑块加上平滑缓动效果
咱们可以用FFmpeg内置的smoothstep函数,或者自定义三角函数缓动公式,让滑块的移动曲线更贴合真实的拖拽动作。同时还能加一条跟随滑块的竖线,让对比边界更清晰,和imgsli的效果更接近。
下面是修改后的完整脚本:
import subprocess def create_comparison_video(image_a, image_b, output_video, duration=5, frame_rate=30, video_width=1920, video_height=1080): ffmpeg_cmd = [ 'ffmpeg', '-y', # 覆盖已存在的输出文件 '-loop', '1', # 循环读取输入图片 '-i', image_a, '-loop', '1', '-i', image_b, '-filter_complex', f"[0]scale={video_width}:{video_height}[img1];" # 将图片A缩放到视频分辨率 f"[1]scale={video_width}:{video_height}[img2];" # 将图片B缩放到视频分辨率 f"[img1][img2]blend=all_expr='if(gte(X,W*smoothstep(0,1,T/{duration})),A,B)':shortest=1," # 用smoothstep实现平滑缓动的滑块移动 f"drawbox=x='W*smoothstep(0,1,T/{duration})-2':y=0:w=4:h={video_height}:color=white:t=fill", # 添加跟随滑块的白色竖线 '-t', str(duration), # 指定视频总时长 '-r', str(frame_rate), # 设置输出帧率 '-c:v', 'libx264', # 使用H.264编码保证兼容性 '-pix_fmt', 'yuv420p', # 适配大多数播放器的像素格式 output_video ] subprocess.run(ffmpeg_cmd, check=True)
关键修改点说明
平滑缓动的核心:
smoothstep函数smoothstep(0,1,T/{duration})会生成一个从0到1的平滑过渡值,替代原来的线性T/{duration}。这个函数的曲线特点是开头和结尾变化缓慢,中间加速,完美模拟人手拖拽滑块的自然节奏。添加可视化滑块线条
新增的drawbox滤镜会在滑块的位置画一条4像素宽的白色竖线,随着滑块同步移动,让观看者能清晰看到两张图片的对比边界,和imgsli的交互感更一致。可选:自定义缓动曲线
如果你想要其他风格的缓动效果,还可以替换smoothstep为其他公式:- 缓入效果(开头慢,后面快):
(T/{duration})*(T/{duration}) - 缓出效果(开头快,后面慢):
1 - (1 - T/{duration})*(1 - T/{duration}) - 正弦曲线缓动(自然的加速减速):
sin((T/{duration})*PI/2)
- 缓入效果(开头慢,后面快):
你可以根据自己的需求替换表达式,多试几次就能找到最贴合你想要的滑块效果啦!
备注:内容来源于stack exchange,提问作者Furkan Gözükara




