我有两个动画(.gif 文件),我想并排运行。这可以用 ImageMagick 来完成吗?
此外,我想在另一个 gif 的三十帧过去后开始播放其中一个 gif。这也可以做到吗?否则,我可以手动将 30 帧黑色帧插入到一张图像中,但使用 ImageMagick 自动执行此步骤会更容易,因为我可能会多次执行此操作。
答案1
这个脚本的作用是:
#!/bin/bash
# $1 : first gif
# $2 : second gif
mkdir first
cd first
convert $1 x%04d.gif
cd ..
mkdir second
cd second
convert $2 x%04d.gif
cd ..
for filename in first/*
do
filename=`basename $filename`
montage -tile 2x1 -geometry 512x512 first/$filename second/$filename concat$filename
done
convert concat* output.gif
rm -rf first
rm -rf second
rm concat*
答案2
ffmpeg“one-liner”没有中间文件
现在 ffmpeg 也可以处理 GIF,因此我们可以使用以下“video side-by-die”问题的答案:将两个视频剪辑合并为一个,将它们并排放置也来解决这个问题。以下命令并排连接两个 GIF,每个 GIF 的高度固定为 300 像素:
ffmpeg \
-i 1.gif \
-i 2.gif \
-filter_complex '
[0]scale=-1:300[a];
[1]scale=-1:300[b];
[a][b]hstack
' \
12.gif
我创建了测试输入 1.gif(480x,蓝色背景,2 秒)和 2.gif(640x,绿色背景,3 秒):
ffmpeg -y -f lavfi -i "
color=blue:480x480:d=2,
drawtext=
fontcolor=black:
fontsize=600:
text='%{eif\:t\:d}':
x=(w-text_w)/2:
y=(h-text_h)/2
" 1.gif
ffmpeg -y -f lavfi -i "
color=green:640x640:d=3,
drawtext=
fontcolor=black:
fontsize=800:
text='%{eif\:t\:d}':
x=(w-text_w)/2:
y=(h-text_h)/2
" 2.gif
该命令创建以下处理图:
1.gif --> [0] --> scale --> [a] --+
|
v
hstack --> 12.gif
^
|
2.gif --> [1] --> scale --> [b] --+
正如我们所看到的,如果一个 GIF 比另一个长,该命令会在最后一帧停止最短的 GIF。
为了改为将视频截断到最短视频的运行时间,我们可以添加如下shortest=1
选项hstack
:
ffmpeg -y -i 1.gif -i 2.gif -filter_complex '[0]scale=-1:300[a];
[1]scale=-1:300[b];[a][b]hstack=shortest=1' 12-short.gif
或者,要垂直堆叠,我们可以使用vstack
筛选,并修复视频宽度而不是高度:
ffmpeg -y -i 1.gif -i 2.gif -filter_complex '[0]scale=300:-1[a];
[1]scale=300:-1[b];[a][b]vstack' 12-vert.gif
当我在本地查看生成的视频时eog
,第一个循环有一些图形伪影。我不知道这是eog
GIF本身的错误还是问题。然而,我没有在浏览器上观察到这一点。
在 Ubuntu 23.10、ffmpeg 6.0 上测试。
答案3
convert
如果提供了超过 1 个输入图像,并且提供了选项,-delay
则如果输出格式为 gif,则将输出动画 gif。
我以前曾使用此链接作为我的参考指南:http://www.imagemagick.org/Usage/anim_basics/