使用 python 以任意顺序从图像制作 GIF
making a GIF from imges in any order with python
我正在尝试在 ubuntu 12.04 中使用 python 语言从一系列 png 格式的图片中制作一个 gif。我有一个文件,里面有我的照片。它们被命名为 lip_shapes1.png 到 lip_shapes11.png。我还有一个包含图像名称的列表,我想按此顺序制作该 gif。列表如下所示:
list = [lip_shapes1.png, lip_shapes4.png , lip_shapes11.png, lip_shapes3.png]
但我的问题是我找到了这段代码:
import os
os.system('convert -loop 0 lip_shapes*.gnp anime.gif')
但它只按 gnp 名称的顺序制作 gif,但我希望它按我想要的顺序排列。可能吗?
如果有人能帮助我,我将不胜感激。
提前致谢
PS: 我也想把它拍成电影。我试过这段代码(形状是我的图像名称列表):
s = Popen(['ffmpeg', '-f', 'image2', '-r', '24', '-i'] + shapes + ['-vcodec', 'mpeg4', '-y', 'movie.mp4'])
s.communicate()
但它在终端中给了我这个并且不起作用:
The ffmpeg program is only provided for script compatibility and will be removed
in a future release. It has been deprecated in the Libav project to allow for
incompatible command line syntax improvements in its replacement called avconv
(see Changelog for details). Please use avconv instead.
Input #0, image2, from 'shz8.jpeg':
Duration: 00:00:00.04, start: 0.000000, bitrate: N/A
Stream #0.0: Video: mjpeg, yuvj420p, 266x212 [PAR 1:1 DAR 133:106], 24 tbr, 24 tbn, 24 tbc
shz8.jpeg 是列表中的第一个名字。
谢谢
因此,您已获得要转换为 gif 的图像列表 python 列表。您可以对其进行排序或按您想要的任何顺序排列。例如
img_list = ['lip_shapes1.png', 'lip_shapes4.png' , 'lip_shapes11.png', 'lip_shapes3.png']
img_list.sort()
请注意list
不应该用作变量名,因为它是列表类型的名称。
然后您可以使用此列表调用 os.system(convert ...)
例如
os.system('convert -loop 0 %s anime.gif' % ' '.join(img_list))
如果您使用 subprocess.call
,您可以将文件名作为字符串列表传递。例如,如果文件名包含引号或空格,这将避免 shell quotation issues。
import subprocess
shapes = ['lip_shapes1.png', 'lip_shapes4.png' , 'lip_shapes11.png', 'lip_shapes3.png']
cmd = ['convert', '-loop0'] + shapes + ['anime.gif']
retcode = subprocess.call(cmd)
if not retval == 0:
raise ValueError('Error {} executing command: {}'.format(retcode, cmd))
你应该确保在这里处理一些事情,如果你想从文件夹中读取一系列 png,我建议使用 for 循环来检查文件的结尾,即 .png、.jpg等。我写了一篇博客 post 介绍如何轻松地做到这一点(阅读它 here):
image_file_names = [],[]
for file_name in os.listdir(png_dir):
if file_name.endswith('.png'):
image_file_names.append(file_name)
sorted_files = sorted(image_file_names, key=lambda y: int(y.split('_')[1]))
这会将所有“.png”文件放入一个文件名向量中。从那里,您可以循环浏览文件以使用以下方法自定义 gif:
images = []
frame_length = 0.5 # seconds between frames
end_pause = 4 # seconds to stay on last frame
# loop through files, join them to image array, and write to GIF called 'test.gif'
for ii in range(0,len(sorted_files)):
file_path = os.path.join(png_dir, sorted_files[ii])
if ii==len(sorted_files)-1:
for jj in range(0,int(end_pause/frame_length)):
images.append(imageio.imread(file_path))
else:
images.append(imageio.imread(file_path))
# the duration is the time spent on each image (1/duration is frame rate)
imageio.mimsave('test.gif', images,'GIF',duration=frame_length)
下面是上述方法生成的示例:
我正在尝试在 ubuntu 12.04 中使用 python 语言从一系列 png 格式的图片中制作一个 gif。我有一个文件,里面有我的照片。它们被命名为 lip_shapes1.png 到 lip_shapes11.png。我还有一个包含图像名称的列表,我想按此顺序制作该 gif。列表如下所示:
list = [lip_shapes1.png, lip_shapes4.png , lip_shapes11.png, lip_shapes3.png]
但我的问题是我找到了这段代码:
import os
os.system('convert -loop 0 lip_shapes*.gnp anime.gif')
但它只按 gnp 名称的顺序制作 gif,但我希望它按我想要的顺序排列。可能吗?
如果有人能帮助我,我将不胜感激。
提前致谢
PS: 我也想把它拍成电影。我试过这段代码(形状是我的图像名称列表):
s = Popen(['ffmpeg', '-f', 'image2', '-r', '24', '-i'] + shapes + ['-vcodec', 'mpeg4', '-y', 'movie.mp4'])
s.communicate()
但它在终端中给了我这个并且不起作用:
The ffmpeg program is only provided for script compatibility and will be removed in a future release. It has been deprecated in the Libav project to allow for incompatible command line syntax improvements in its replacement called avconv (see Changelog for details). Please use avconv instead.
Input #0, image2, from 'shz8.jpeg': Duration: 00:00:00.04, start: 0.000000, bitrate: N/A Stream #0.0: Video: mjpeg, yuvj420p, 266x212 [PAR 1:1 DAR 133:106], 24 tbr, 24 tbn, 24 tbc
shz8.jpeg 是列表中的第一个名字。
谢谢
因此,您已获得要转换为 gif 的图像列表 python 列表。您可以对其进行排序或按您想要的任何顺序排列。例如
img_list = ['lip_shapes1.png', 'lip_shapes4.png' , 'lip_shapes11.png', 'lip_shapes3.png']
img_list.sort()
请注意list
不应该用作变量名,因为它是列表类型的名称。
然后您可以使用此列表调用 os.system(convert ...)
例如
os.system('convert -loop 0 %s anime.gif' % ' '.join(img_list))
如果您使用 subprocess.call
,您可以将文件名作为字符串列表传递。例如,如果文件名包含引号或空格,这将避免 shell quotation issues。
import subprocess
shapes = ['lip_shapes1.png', 'lip_shapes4.png' , 'lip_shapes11.png', 'lip_shapes3.png']
cmd = ['convert', '-loop0'] + shapes + ['anime.gif']
retcode = subprocess.call(cmd)
if not retval == 0:
raise ValueError('Error {} executing command: {}'.format(retcode, cmd))
你应该确保在这里处理一些事情,如果你想从文件夹中读取一系列 png,我建议使用 for 循环来检查文件的结尾,即 .png、.jpg等。我写了一篇博客 post 介绍如何轻松地做到这一点(阅读它 here):
image_file_names = [],[]
for file_name in os.listdir(png_dir):
if file_name.endswith('.png'):
image_file_names.append(file_name)
sorted_files = sorted(image_file_names, key=lambda y: int(y.split('_')[1]))
这会将所有“.png”文件放入一个文件名向量中。从那里,您可以循环浏览文件以使用以下方法自定义 gif:
images = []
frame_length = 0.5 # seconds between frames
end_pause = 4 # seconds to stay on last frame
# loop through files, join them to image array, and write to GIF called 'test.gif'
for ii in range(0,len(sorted_files)):
file_path = os.path.join(png_dir, sorted_files[ii])
if ii==len(sorted_files)-1:
for jj in range(0,int(end_pause/frame_length)):
images.append(imageio.imread(file_path))
else:
images.append(imageio.imread(file_path))
# the duration is the time spent on each image (1/duration is frame rate)
imageio.mimsave('test.gif', images,'GIF',duration=frame_length)
下面是上述方法生成的示例: