每天学习一点新知识(三)——用文字来填充一段视频
接着上次用文字组成一张图片,这一次来解释一下用文字填充一段视频的代码。
准备工作什么的就不说了,和上次都一样。
直接上代码,解释代码就好了。
话不多说,直接开始
要达到我们的目的,需要写三个py文件,分别实现三个步骤。
1、将视频按帧拆分成图片
import cv2
import os
#要提取视频的文件名,隐藏后缀
sourceFileName='video'
#在这里把后缀接上
video_path = os.path.join("", "", sourceFileName+'.mp4')
times=0
#提取视频的频率,每帧提取一个,这个可以根据情况进行更改
#因为每帧都取的话,一个3、4分钟的视频大概就会生成五六千张图片,会很占空间
frameFrequency=1
#输出图片到当前目录video文件夹下
outPutDirName='./'+sourceFileName+'/'
if not os.path.exists(outPutDirName):
#如果文件目录不存在则创建目录
os.makedirs(outPutDirName)
camera = cv2.VideoCapture(video_path)
while True:
# 逐帧读取,times记录当前帧数
times+=1
res, image = camera.read()
if not res:# 所有帧读完,退出
print('not res , not image')
break
if times%frameFrequency==0: # 当前帧是需要输出的,那就生成图片
cv2.imwrite(outPutDirName + str(times)+'.jpg', image)
print(outPutDirName + str(times)+'.jpg')
print('图片提取结束')
camera.release()
2、将提取出来的图片用文字填充
这一部分的代码和上一篇的代码一样,具体的注释都在上一篇有讲过了。
区别仅有一点,就是上次只处理一张图片,而这次处理一个目录的图片,所以在调用函数时要加一个循环。
#-*- coding:utf-8 -*-
import os
from PIL import Image, ImageFont, ImageDraw
def draw(pic):
str_out = '明日方舟'
imin = Image.open("video/"+pic,"r")
height = imin.height
width = imin.width
font=ImageFont.truetype("./方正隶书简.TTF", 12, encoding="unic")#获取字体
font_w,font_h=font.getsize(str_out[0]) #6, 11
imout = Image.new("RGB",(imin.width,imin.height),'black')
colors = []
k = 0
for i in range(0, imin.height, font_h):
color = []
for j in range(0, imin.width, font_w):
# print(i, j)
pixel = imin.getpixel((j,i))
color.append((pixel[0],pixel[1],pixel[2]))#记录像素颜色信息
colors.append(color)
print(len(colors), len(colors[0]))
draw = ImageDraw.Draw(imout)
print(font_h, font_w)
for i in range(0, imin.height, font_h):
k = 0
for j in range(0, imin.width, font_w):
draw.text([j, i],str_out[k],colors[i // font_h][j // font_w], font)
k+=1
k%=len(str_out)
#输出
imout.save(outPutDirName+"/new_"+pic+".jpg", encoding='utf-8')
outPutDirName='./new/'
if not os.path.exists(outPutDirName):
#如果文件目录不存在则创建目录
os.makedirs(outPutDirName)
filelist = os.listdir('video')
# 读取指定目录中所有文件,遍历处理
for file in filelist:
draw(file);
3、将处理完的图片重新组成视频
import time
import os
import cv2
import re
def resort(list):
# 对根据文件名读取的图片进行排序,不是必须的,
for i in range(len(list)-1):
for j in range(len(list)-1):
if int(re.findall(r'\d+', list[j])[0]) > int(re.findall(r'\d+', list[j+1])[0]):
list[j], list[j+1] = list[j+1], list[j]
return list
def picvideo(path, size):
# path是读入的图片所在的文件夹,size是图片分辨率,如果指定分辨率的图片不存在,生成的视频将无法打开
filelist = os.listdir(path) # 获取该目录下的所有文件名
filelist = resort(filelist)# 给图片文件进行排序
fps = 10 # fps表示一秒读入/播放的图片数
file_path = 'new.mp4' # 生成视频的路径
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
# 根据视频编码确定生成视频的格式,这里代表要生成mp4格式视频
video = cv2.VideoWriter(file_path, fourcc, fps, size)
for item in filelist:
if item.endswith('.jpg'): # 判断图片后缀是否是.jpg(.png也可以)
item = path + '/' + item
img = cv2.imread(item) # 使用opencv读取图像
video.write(img) # 把图片写进视频
video.release() # 释放
picvideo(r'new', (1920, 1080))
以上就是生成一段由文字生成的视频的全部步骤了,只要按顺序将三个文件依次执行就可以了。当然,为了方便,可以再加一个新建一个文件写主函数来依次执行三个文件。
4、效果展示
大家也可以直接下载代码使用。
感谢阅读。