一个简单的通过Python将视频文件转换为gif动图的示例。
1. 准备工作
安装cv2, imageio库
pip install cv2
pip install imageio
2. 代码
整个代码部分主要有两大块,即两个函数实现,一个是 extract_image_from_video 实现从视频文件中抽取图片的操作,另一个是 make_gif 实现通过图片构建 gif 图。
首先导入需要的库
import cv2
import os
import imageio
2.1. 从视频文件中抽帧
若原始视频文件每秒帧数为 fps,我们每秒只想保留 cap_fps 帧,那么我们只需每隔 fps // cap_fps 帧取一帧即可。
def extract_image_from_video(video_path_name=None, img_dir='img/', cap_fps=10):
'''
从视频中提取图片
:param video_path_name: 视频文件全路径
:param img_dir: 截图存放文件夹路径
:param cap_fps: 每秒截图数量
:return:
'''
# 创建文件夹用于保存从video中提取的图像
if not os.path.exists(img_dir):
os.mkdir(img_dir)
else:
for file_name in os.listdir(img_dir):
os.remove(img_dir + file_name)
cap = cv2.VideoCapture(video_path_name) # 打开视频文件
# 视频文件的一些信息(name,fps,size)
video_name = ''.join(video_path_name.split('/')[-1].split('.')[:-1])
fps = cap.get(cv2.CAP_PROP_FPS)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('Video info : ', {'name': video_name, 'fps': fps, 'size': size})
temp = fps // cap_fps # 根据每秒视频提取图片数计算何时保存视频文件
frame_nb = 1 # 当前视频帧数
while (cap.isOpened()):
ret, frame = cap.read()
if ret == True:
# 以下被注释语句用于显示视频
# cv2.imshow('frame', frame)
if frame_nb % temp == 0:
# 保存视频当前帧, 文件名应按字符大小升序保存
cv2.imwrite(img_dir + video_name + '%3d.png' % frame_nb, frame)
else:
break
frame_nb += 1
cap.release()
cv2.destroyAllWindows()
2.2. 通过图片构建gif图
def make_gif(gif_name='new.gif', duration=0.1):
'''
通过截图得到 *.gif文件
:param gif_name: 存放gif文件全路径
:param duration: gif中每一张图片(每一帧)持续时间
:return:
'''
image_list = [img_dir + img_name for img_name in os.listdir(img_dir)]
frames = []
for image_name in image_list:
frames.append(imageio.imread(image_name))
imageio.mimsave(gif_name, frames, 'GIF', duration=duration)
2.3. 运行
if __name__ == '__main__':
extract_image_from_video(video_path_name='xxx.mp4')
make_gif()
然后就可以在根目录下找到新创建的 new.gif 啦!
3. 其它
除了常规的异常检测外优化,
- 若只想取视频一部分制作gif,则可以再 extract_image_from_video 中根据 fps 计算并添加 start_frame_number, end_frame_number 作为限制。
- 若想要减小 gif 文件的大小,一个是可以通过调整 cap_fps 减少抽取图片数量,另一个是可以在制作 gif 时通过等量的缩放每一帧图片。
Enjoy yourself !