FFmpeg图片转视频遇到‘width not divisible by 2’?别急着改图,试试这个参数一步到位
FFmpeg图片转视频遇到‘width not divisible by 2’别急着改图试试这个参数一步到位第一次用FFmpeg把图片转成视频时看到width not divisible by 2的错误提示我下意识打开了Photoshop准备调整图片尺寸。直到发现FFmpeg自带的scale滤镜可以自动处理这个问题才意识到自己走了弯路。对于开发者来说手动预处理图片不仅效率低下在批量处理时更是灾难。本文将分享几种直接在FFmpeg命令行中解决尺寸问题的专业方案。1. 为什么H.264编码要求宽度能被2整除H.264作为目前最流行的视频编码标准其压缩算法基于宏块(macroblock)结构。每个宏块的大小是16x16像素而宏块又可以进一步划分为4x4的子块进行更精细的编码处理。这种分层块处理机制带来了两个关键限制最小处理单元编码器需要以4x4或16x16为最小单位处理图像数据边界对齐图像边缘必须与这些块边界对齐否则无法完成分块编码当遇到497x373这样宽度为奇数的图片时H.264编码器会因为无法将最后一个像素列放入完整的4x4块而报错。下表对比了不同编码标准对尺寸的要求编码标准宽度要求高度要求典型应用场景H.264能被2整除能被2整除通用视频流H.265能被2整除能被2整除4K/8K视频VP9无限制无限制Web视频AV1无限制无限制新一代流媒体提示虽然VP9和AV1没有严格限制但保持尺寸为偶数仍有助于提高编码效率2. 自动调整尺寸的三种FFmpeg方案2.1 使用scale滤镜自动取整最直接的解决方案是在视频滤镜链中加入scale滤镜ffmpeg -loop 1 -i input.jpg -vf scaletrunc(iw/2)*2:trunc(ih/2)*2 -c:v libx264 -t 10 output.mp4这个命令中的关键部分scaletrunc(iw/2)*2:trunc(ih/2)*2工作原理如下iw/2和ih/2分别计算宽度和高度的一半trunc()函数对结果取整去掉小数部分乘以2后得到最接近原始尺寸的偶数例如497x373的图片会变为496x372仅损失1个像素的宽度和高度视觉上几乎无法察觉差异。2.2 使用pad滤镜添加黑边对于需要保持原始尺寸的情况可以使用pad滤镜添加1像素的黑边ffmpeg -loop 1 -i input.jpg -vf padwidthceil(iw/2)*2:heightceil(ih/2)*2 -c:v libx264 -t 10 output.mp4这里ceil()函数会向上取整所以497x373会变为498x374。两种方法的对比如下方法宽度处理高度处理适用场景scale(trunc)向下取整向下取整允许轻微裁剪pad(ceil)向上取整向上取整必须保留全部内容manual手动调整手动调整特殊尺寸需求2.3 批量处理脚本示例当需要处理大量图片时可以编写简单的shell脚本#!/bin/bash for img in *.jpg; do ffmpeg -loop 1 -i $img \ -vf scaletrunc(iw/2)*2:trunc(ih/2)*2 \ -c:v libx264 -t 3 ${img%.*}.mp4 done这个脚本会遍历当前目录下所有jpg文件为每个文件生成3秒时长的MP4视频。3. 高级应用场景与技巧3.1 保持宽高比的精确调整有时简单的取整可能会轻微改变宽高比。以下命令可以在调整尺寸的同时保持原始比例ffmpeg -loop 1 -i input.jpg \ -vf scaleiw:sar*iw,trunc(ow/2)*2:trunc(oh/2)*2 \ -c:v libx264 -t 10 output.mp4其中sar表示样本宽高比确保调整后的尺寸不会导致图像变形。3.2 与其他滤镜链结合使用scale/pad滤镜可以与其他处理步骤组合。例如先调整尺寸再添加水印ffmpeg -loop 1 -i input.jpg \ -i watermark.png \ -filter_complex [0:v]scaletrunc(iw/2)*2:trunc(ih/2)*2[bg];[bg][1:v]overlay10:10 \ -c:v libx264 -t 10 output.mp43.3 性能优化参数对于高质量输出可以添加这些优化参数ffmpeg -loop 1 -i input.jpg \ -vf scaletrunc(iw/2)*2:trunc(ih/2)*2 \ -c:v libx264 -preset slower -crf 18 \ -pix_fmt yuv420p -t 10 output.mp4-preset slower提高压缩效率-crf 18设置视觉无损质量-pix_fmt yuv420p确保兼容所有播放器4. 常见问题排查4.1 滤镜语法错误如果收到Invalid argument或Unrecognized option错误检查确保FFmpeg版本≥4.0旧版可能不支持某些语法滤镜参数中的引号和逗号使用正确所有数学函数名拼写正确trunc/ceil等4.2 输出视频闪烁问题使用-loop 1时某些版本可能会出现第一帧闪烁。解决方案是添加-framerate参数ffmpeg -loop 1 -framerate 30 -i input.jpg \ -vf scaletrunc(iw/2)*2:trunc(ih/2)*2 \ -c:v libx264 -t 10 output.mp44.3 内存不足处理大图处理超高分辨率图片时可能遇到内存限制。可以添加-max_muxing_queue_size 1024参数ffmpeg -loop 1 -i large.jpg \ -vf scaletrunc(iw/2)*2:trunc(ih/2)*2 \ -max_muxing_queue_size 1024 \ -c:v libx264 -t 10 output.mp4在实际项目中我发现scale滤镜配合trunc计算是最可靠的解决方案特别是在自动化处理流水线中。相比手动预处理图片这种方法不仅节省时间还能确保处理过程的一致性和可重复性。