如何用FFmpeg调整帧拼贴网格维度且保留帧顺序?
FFmpeg 帧拼贴网格重排解决方案
一、通用顺序重排(无需自定义映射)
如果原拼贴和目标拼贴的总帧数一致(比如你例中9列2行=18帧,6列3行=18帧),直接用untile拆分单帧,再用tile按新网格拼接,是最高效的方式,完全保留原左→右、上→下的帧顺序:
命令示例
假设原拼贴为input.jpg(1080×240,9列2行),目标是720×480的6列3行拼贴:
ffmpeg -i input.jpg -vf "untile=cols=9:rows=2,tile=cols=6:rows=3" output.jpg
untile=cols=9:rows=2:将原拼贴拆分为18个独立帧,顺序严格遵循原拼贴的排列逻辑tile=cols=6:rows=3:把拆分后的帧按新网格规则重新拼接,自动继承原顺序
二、自定义位置映射表的进阶实现
如果需要按自定义映射表调整帧位置(而非单纯行列转换),可以通过crop提取单帧,再用overlay按映射规则叠加到新画布上:
步骤与命令示例
假设原拼贴宽1080、高240,目标拼贴宽720、高480,映射表定义了每个原帧的提取坐标和目标位置:
ffmpeg -i input.jpg -lavfi " # 拆分原拼贴为多个流,对应每个帧 split=18[v0][v1][v2][v3][v4][v5][v6][v7][v8][v9][v10][v11][v12][v13][v14][v15][v16][v17]; # 逐个提取原帧(crop参数:crop=帧宽:帧高:原左上角X:原左上角Y) [v0]crop=120:120:0:0[v0_c]; # 原第1帧:宽=1080/9=120,高=240/2=120 [v1]crop=120:120:120:0[v1_c]; # ... 依次完成所有18个帧的提取 [v17]crop=120:120:960:120[v17_c]; # 创建目标尺寸的黑色画布 color=black:720x480[canvas]; # 按映射表顺序将帧叠加到画布(overlay参数:overlay=目标左上角X:目标左上角Y) [canvas][v0_c]overlay=0:0[step1]; [step1][v1_c]overlay=120:0[step2]; # ... 按目标网格的排列顺序,依次叠加对应原帧 [step17][v17_c]overlay=600:360[final] " -map "[final]" output.jpg
- 批量处理提示:如果映射表条目较多,建议用脚本(比如Python)遍历映射表自动生成
crop和overlay的滤镜片段,避免手动重复操作。
关于select滤镜的澄清
select滤镜核心作用是按帧索引筛选特定帧(比如select='eq(n,5)'选择第6帧,索引从0开始)。在本场景中,若只是按原顺序重排,untile+tile已经足够;若需要自定义帧顺序,select可配合concat滤镜拼接指定顺序的单帧,但效率不如直接用overlay在画布上叠加。
内容的提问来源于stack exchange,提问作者JamesK
相关产品推荐
相关产品推荐

