如何连接两个GIF以在Python中一个接一个地播放



如果我有两个GIF,GIF 1长10秒,GIF 2长5秒,有没有办法连接它们,这样最终的GIF总共长15秒?

一旦在内存中读取了所有帧,我是否必须用imageio.mimread()和输出循环遍历两个GIF的每一帧?

或者还有其他方法可以知道开始和结束时间并改变它吗?

编辑:FirefoxMetzger提供的解决方案非常Python化,如果您不想安装gifsicle等其他软件/包,则非常理想。

import imageio.v3 as iio
import numpy as np
frames = np.vstack([
iio.imread("imageio1.gif"),
iio.imread("imageio2.gif"),
])
# get duration each frame is displayed
iio.imwrite("imageio_combined.gif", frames)

两个GIF在15.6秒内完成,每个GIF包含100帧。

但是,如果运行时间很重要,我推荐gifsicle:

gifsicle(
sources=["imageio1.gif", "imageio2.gif"], # or just omit it and will use the first source provided.
destination="imageio3.gif",
options=["--optimize=2", "--threads=2", "--no-conserve-memory"]
)

这只需4.8秒,速度是它的三倍。

确切的解决方案取决于GIF是否具有相同的FPS。如果他们这样做了,你可以简单地将他们连接起来,就可以开始了。

import imageio.v3 as iio
import numpy as np
frames = np.vstack([
iio.imread("my_first.gif"),
iio.imread("my_second.gif"),
])
# get duration each frame is displayed
duration = iio.immeta("my_first.gif")["duration"]
iio.imwrite("combined.gif", frames, duration=duration)

如果GIF没有相同的帧速率,事情就会变得更加复杂。在这里,在连接这两个GIF之前,您首先必须对它们的FPS进行规范化。我建议使用ImageIO的pyav插件,它允许将此过程委派给FFMPEG:

import imageio.v3 as iio
import numpy as np
# make sure pyav is installed (pip install av)
frames = np.vstack([
iio.imread(
"my_first.gif",
plugin="pyav",
# normalize the GIF to 50 FPS
filter_sequence=[("fps", "50")]
),
iio.imread(
"my_second.gif",
plugin="pyav",
# normalize the GIF to 50 FPS
filter_sequence=[("fps", "50")]
),
])
iio.imwrite("combined.gif", frames, duration=20)

您已经找到了一种方法,但当您提到imageio时,让我用它添加一个答案。至少在旧的imageio v2 API中,即使更详细,它也是一个非常简单的业务。

import imageio
gif_1 = imageio.get_reader(path_gif_1)
gif_2 = imageio.get_reader(path_gif_2)
combined_gif = imageio.get_writer('combined.gif')
for frame in gif_1:
combined_gif.append_data(frame)
for frame in gif_2:
combined_gif.append_data(frame)
gif_1.close()
gif_2.close()    
combined_gif.close()

我认为这是有效的:

from pygifsicle import gifsicle
gifsicle(
sources=["imageio_00.gif", "imageio_01.gif"], # or a single_file.gif
destination="destination.gif", # or just omit it and will use the first source provided.
optimize=True, # Whetever to add the optimize flag of not
colors=256, # Number of colors t use
options=["--verbose"] # Options to use.
)

相关内容

最新更新