ImageMagick - 使用IM convert将2个GIF制作成并排的GIF

15

我有两个长度相同的GIF图像。

我想将这两个GIF并排放置,使它们同时播放成为一个GIF。我尝试使用convert工具:

convert +append 1.gif1 2.gif output.gif

然而,这似乎将所有图像混合在一起,并将大小改小得极其严重。

我想可以把每个图像连接起来,然后创建一个 GIF,但是当我尝试时它并没有成功:

convert -delay 15 -loop 0 1*.png 2*.png +append output.gif

我有很多文件名很长的图片,我不想一个个去修改每个图片的名称以符合新的命名规范。

1个回答

29

我没有两个相同长度的动态图像,所以我将使用这个动态图像的两份副本:

enter image description here

让我们通过以下方式查看其中的帧:

identify 1.gif
1.gif[0] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[1] GIF 449x339 500x339+51+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[2] GIF 449x339 500x339+51+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[3] GIF 449x339 500x339+51+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[4] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[5] GIF 449x339 500x339+51+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[6] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[7] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[8] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[9] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[10] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[11] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[12] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[13] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[14] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[15] GIF 448x339 500x339+52+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[16] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000
1.gif[17] GIF 500x339 500x339+0+0 8-bit sRGB 32c 508KB 0.000u 0:00.000

有18个不同大小的帧,这意味着我们需要使用-coalesce将部分帧重建为完整帧。

让我们复制它并制作2.gif

cp 1.gif 2.gif

现在,我们可以将这两个gif分成它们各自的组成帧,就像这样:
convert 1.gif -coalesce a-%04d.gif     # split frames of 1.gif into a-0001.gif, a-0002.gif etc
convert 2.gif -coalesce b-%04d.gif     # split frames of 2.gif into b-0001.gif, b-0002.gif etc

现在让我们将单个帧并排拼接起来:
for f in a-*.gif; do convert $f ${f/a/b} +append $f; done

请注意,${f/a/b}是Bash的一个特性,意思是“取f的值,并将字母'a'替换为'b'”。
然后再将它们组合起来:
convert -loop 0 -delay 20 a-*.gif result.gif

这看起来比实际上更长,更难,因为我试图解释所有内容,但它实际上是这样的:

convert 1.gif -coalesce a-%04d.gif                         # separate frames of 1.gif
convert 2.gif -coalesce b-%04d.gif                         # separate frames of 2.gif
for f in a-*.gif; do convert $f ${f/a/b} +append $f; done  # append frames side-by-side
convert -loop 0 -delay 20 a-*.gif result.gif               # rejoin frames

注意,这只是概念代码,不是生产质量。它不会删除它创建的临时文件,也不会将原始GIF的帧间时间传递到后续处理中。如果您想获取原始帧速率,可以像这样获取它们并将它们保存到数组中,然后在重新动画命令中反馈延迟:

enter image description here

identify -format "%f[%s] %T\n" 1.gif
1.gif[0] 8
1.gif[1] 8
1.gif[2] 8
1.gif[3] 8
1.gif[4] 8
1.gif[5] 8
1.gif[6] 8
1.gif[7] 8
1.gif[8] 8
1.gif[9] 8
1.gif[10] 11
1.gif[11] 11
1.gif[12] 11
1.gif[13] 11
1.gif[14] 11
1.gif[15] 11
1.gif[16] 11
1.gif[17] 26

此外,您可能希望在两个动画之间添加一个间距,比如10像素,您可以通过将for循环中的convert命令替换为以下命令来实现:

convert $f -size 10x xc:none ${f/a/b} +append $f

enter image description here


我正在使用ImageMagic(v7.0.2),所有命令都很好用,除了for f in a-*.gif; do convert $f ${f/a/b} +append $f; done。根据FOR循环的文档,我将其更改为:FOR %f in (a-*.gif); DO convert %f %{f/a/b} +append %f; done,但我仍然遇到麻烦。有什么建议吗?我正在使用的FOR循环文档在这里(http://www.imagemagick.org/Usage/windows/#for_loops),附加命令我正在使用是:(http://www.imagemagick.org/discourse-server/viewtopic.php?t=11320)。 - AaronJPung
3
${f/a/b} 的意思是“取 f 并将其中所有的 a 替换为 b”,它是特定于 Linux 操作系统中的 bash 命令。你需要找到在 Windows 操作系统下相应的方法来实现该功能。 - Mark Setchell
谢谢确认。是的,我已经注意到了我包含的链接中的语法差异。我认为在Windows中,$符号应该改成%符号。我会继续努力的。 - AaronJPung
你不是在使用Windows系统,希望是这样吧? - Mark Setchell
1
已经将近三年过去了,这仍然是我找到的最佳解决方案。谢谢!相比之下,只是使用“montage -tile 2x1…”(具有相同尺寸和nframes)的结果看起来很糟糕(为什么?)。 - Theophrastus
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接