python|使用python实现代码动画视频

使用python实现代码动画视频 前言 最近在CSDN上面看到一个将视频转换为由代码组成的视频,所以想自己写一个。参考的原文博客为:https://blog.csdn.net/hhladminhhl/article/details/118463344
功能:使用python实现将动画转换为有字符组成的视频。
实现方法分为如下几步:
1、将视频从网站上面下载下来
2、将视频截取为GIF,把截取的GIF进行ASCII字符转换
3、将转换好的字符gif根据每一帧的顺序进行重命名,然后排序
4、将排序后的每一帧gif图片转换为jpg图片
5、将字符图片合成视频
实现步骤 1、准备阶段
想要将视频制作出来,我们想要用到如下几个工具:
(1)、将视频下载下来的工具,我这里使用的是you-get。
you-get安装方法:
下载的命名:

pip install you-get

下载you-get截图:
python|使用python实现代码动画视频
文章图片

确认you-get下载成功截图:
python|使用python实现代码动画视频
文章图片

(2)、将视频转换为GIF图的工具,我这里使用的是迅捷视频转换器。
迅捷视频转换器下载地址:https://www.xunjieshipin.com/video-converter
迅捷视频转换器使用界面截图:
python|使用python实现代码动画视频
文章图片

(3)、将GIF转换为字符的工具,我这里使用的是ASCII Animator
ASCII Animator下载地址:http://www.qqpr.com/
(4)、在文件中需要使用到的库:cv2、os、opecv-python
下载需要使用的命名:
pip install cv2 # 用于处理图像的库 pip install os # 用于处理文件的库 pip install opencv-python # 用于处理图像的库

2、下载视频
通过you-get将视频下载到本地,我这里使用的是《如果历史是一群喵第六季》的op。
《如果历史是一群喵第六季》视频链接:
https://www.bilibili.com/bangumi/play/ep399825
下载视频使用的命令:
you-get -o 本地保存路径 视频链接

下载视频过程截图:
python|使用python实现代码动画视频
文章图片

这样我们就成功将视频下载到本地
python|使用python实现代码动画视频
文章图片

3、截取GIF图
接下来将下载后的视频进行GIF截取,我这里使用的是迅捷视频转换器。注意:截取视频时长尽量不能太长,否则在进行ASCII转换时会因为内存不够而报错,每次截取3s。
迅捷视频转换器截取GIF过程截图:
python|使用python实现代码动画视频
文章图片

python|使用python实现代码动画视频
文章图片

将截取出来的gif文件安装顺序1、2、3将gif命名。
python|使用python实现代码动画视频
文章图片

4、将GIF转换为ASCII
使用ASCII Animator将截取的GIF每一帧图片转换为ASCII。注意:需要设置每100个像素宽度的字符数(我设置的是75)和输出类型选择动画ASCII(.gif)。
使用ASCII Animator截图。由于转换后图片占用内存太大,所以只用一个gif进行举例。
python|使用python实现代码动画视频
文章图片

我们可以在输出路径里面找到gif每一帧转换的ASCII的gif,将gif复制到python项目下material/img文件夹中,以便后续的处理(在复制文件时按照自己的需求确定复制路径)。
5、gif文件重命名
思路:使用os.listdir(path)读取路径下所有的文件名称,然后通过for遍历每一个文件、使用os.rename(src, dst)对文件重命名。
实现代码:
# 导入包 import os import cv2 from PIL import Image# 定义重命名的函数 def rename_gif(gif_path): """ 定义重命名的函数 :param gif_path: gif图片存储的路径 :return: """ # 使用os.listdir(path)读取路径下所有的文件名称 file_list = os.listdir(gif_path) # 使用len()获取文件夹下文件的数量 n = len(file_list) # 使用for循环遍历文件夹下的所有文件 for i in range(n): s = str(file_list[i])# 获取第i个文件的名称 src = https://www.it610.com/article/gif_path + s# 重命名前名称 dst = gif_path + s[8: 10] + s[-4:]# 重命名后名称 os.rename(src, dst)# 对文件重命名rename_gif('./material/img/') # 调用重命名函数

gif重命名后,所有的gif已经按照每一帧的顺序排列好了,后续处理时按照图片名称进行处理就行了。
重命名后的图片:
python|使用python实现代码动画视频
文章图片

6、将gif转换为jpg图片
按照帧顺序排列的gif转换为jpg图片。注意:不能直接将文件后缀名该为jpg,那样文件格式还是没有变,使用cv2读取时会为空。
思路:
1、使用os.listdir(path)读取路径下所有的文件名称
2、使用Image.open(path)读取gif格式的图片
3、使用im.convert(‘RGB’)将图片格式转换为jpg格式
4、使用frame.save()将转换后的图片写回文件夹。
实现的代码:
# 导入包 import os import cv2 from PIL import Image# 定义用于迭代图片数据的函数 def iter_frames(im): try: i = 0 while 1: im.seek(i) imframe = im.copy() if i == 0: palette = imframe.getpalette() else: imframe.putpalette(palette) yield imframe i += 1 except EOFError: pass# 定义将gif图片转换为jpg图片的函数 def gif2jpg(gif_path, jpg_path): """ 定义将gif图片转换为jpg图片的函数 :param gif_path: 存储gif图片的路径 :param jpg_path: 存储jpg图片的路径 :return: """ # 获取所有gif图片名称 file_list = os.listdir(gif_path) # 将图片排序,以名称字符串的数字进行排列 file_list.sort(key=lambda x: int(x[: -4])) # 使用for循环读取所有的gif图片 for img in file_list: # 判断是否为gif格式的图片 if img[-4:] == '.gif': im = Image.open(gif_path + img)# 打开图片 im = im.convert('RGB')# 转换格式 # 当存储jpg图片的路径不存在时创建路径 if not os.path.exists(jpg_path): os.makedirs(jpg_path) # 进行图片的转换 for i, frame in enumerate(iter_frames(im)): frame.save(jpg_path + img[0: -4] + '.jpg', **frame.info)gif2jpg('./material/img/', './img/')# 调用将gif转换为jpg的函数

转换后的图片:
python|使用python实现代码动画视频
文章图片

7、将图片合成视频
思路:
1、使用os.listdir(path)读取路径下所有的文件名称
2、使用cv2.VideoWriter_fourcc(‘m’, ‘p’, ‘4’, ‘v’)确定视频格式为.mp4
3、使用Image.open(path)打开一张图片,用于确定合成视频的宽度和高度。
4、使用cv2.VideoWriter(video_path, fourcc, fps, im.size)创建视频,video_path确定视频存储路径,fourcc确定视频格式,fps确定视频每一秒帧数,im.size确定视频宽度和高度。
5、使用cv2.imread(path)读取需要插入视频的图片
6、使用video_writer.write(frame)将图片写入视频中。
7、使用video_writer.release()将视频释放。
实现过程的代码:
# 导入包 import os import cv2 from PIL import Image# 定义图片转换为视频的函数 def jpg2video(jpg_path, video_path): """ 定义图片转换为视频的函数 :param jpg_path: jpg图片所在文件夹 :param video_path: 视频存储路径 :return: """ # 使用os.listdir(path)获取所有jpg图片名称 jpg_list = os.listdir(jpg_path) # 将图片排序,以名称字符串的数字进行排列 jpg_list.sort(key=lambda x: int(x[: -4])) fps = 21# 定义每一秒的帧数 # 视频格式为mp4格式 fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') im = Image.open(jpg_path + jpg_list[0])# 打开第一张图片 # 设置写入视频的要求,参数(写入的路径, 格式, 每一秒的帧数,视频宽高) video_writer = cv2.VideoWriter(video_path, fourcc, fps, im.size) print(jpg_list) # 使用for循环将图片写入视频中 for jpg_i in jpg_list: frame = cv2.imread(jpg_path + jpg_i)# 使用cv2导入图片 print('开始将' + jpg_i + '加入视频') video_writer.write(frame)# 将图片加入视频 video_writer.release()# 释放video_writerjpg2video('./img/', './video.mp4')# 调用图片转换为视频函数

【python|使用python实现代码动画视频】最终的效果:
python|使用python实现代码动画视频
文章图片

8、完整的代码
""" 功能:将图片合成一个视频 """ # 导入包 import os import cv2 from PIL import Image# 第一步将gif图像重命名 # 定义重命名的函数 def rename_gif(gif_path): """ 定义重命名的函数 :param gif_path: gif图片存储的路径 :return: """ # 使用os.listdir(path)读取路径下所有的文件名称 file_list = os.listdir(gif_path) # 使用len()获取文件夹下文件的数量 n = len(file_list) # 使用for循环遍历文件夹下的所有文件 for i in range(n): s = str(file_list[i])# 获取第i个文件的名称 src = https://www.it610.com/article/gif_path + s# 重命名前 dst = gif_path + s[8: 10] + s[-4:]# 重命名后 os.rename(src, dst)# 对文件重命名# 第二步将gif图片转换为jpg图片 # 定义用于迭代图片数据的函数 def iter_frames(im): try: i = 0 while 1: im.seek(i) imframe = im.copy() if i == 0: palette = imframe.getpalette() else: imframe.putpalette(palette) yield imframe i += 1 except EOFError: pass# 定义将gif图片转换为jpg图片的函数 def gif2jpg(gif_path, jpg_path):""" 定义将gif图片转换为jpg图片的函数 :param gif_path: 存储gif图片的路径 :param jpg_path: 存储jpg图片的路径 :return: """ # 获取所有gif图片名称 file_list = os.listdir(gif_path) # 将图片排序,以名称字符串的数字进行排列 file_list.sort(key=lambda x: int(x[: -4])) # 使用for循环读取所有的gif图片 for img in file_list: # 判断是否为gif格式的图片 if img[-4:] == '.gif': im = Image.open(gif_path + img)# 打开图片 im = im.convert('RGB')# 转换格式 # 当存储jpg图片的路径不存在时创建路径 if not os.path.exists(jpg_path): os.makedirs(jpg_path) # 进行图片的转换 for i, frame in enumerate(iter_frames(im)): frame.save(jpg_path + img[0: -4] + '.jpg', **frame.info)# 第三步将图片转换为视频 # 定义图片转换为视频的函数 def jpg2video(jpg_path, video_path): """ 定义图片转换为视频的函数 :param jpg_path: jpg图片所在文件夹 :param video_path: 视频存储路径 :return: """ # 使用os.listdir(path)获取所有jpg图片名称 jpg_list = os.listdir(jpg_path) # 将图片排序,以名称字符串的数字进行排列 jpg_list.sort(key=lambda x: int(x[: -4])) fps = 21# 定义每一秒的帧数 # 视频格式为mp4格式 fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') im = Image.open(jpg_path + jpg_list[0])# 打开第一张图片 # 设置写入视频的要求,参数(写入的路径, 格式, 每一秒的帧数,视频宽高) video_writer = cv2.VideoWriter(video_path, fourcc, fps, im.size) print(jpg_list) # 使用for循环将图片写入视频中 for jpg_i in jpg_list: frame = cv2.imread(jpg_path + jpg_i)# 使用cv2导入图片 print('开始将' + jpg_i + '加入视频') video_writer.write(frame)# 将图片加入视频 video_writer.release()# 释放video_writer# rename_gif('./material/img/') # 调用重命名函数 #gif2jpg('./material/img/', './img/')# 调用将gif转换为jpg的函数 jpg2video('./img/', './video.mp4')# 调用图片转换为视频函数

    推荐阅读