python将视频像素抓取替换导出mosaic效果的文本视频
第一次写博客,关于python的。
全网关于这种视频的的合成代码几乎没有,所以我提供了一套这样的思路。
完成过程很痛苦。因为全网类似的太少。
最近很火的武大樱花开,用代码敲出樱花盛开的场景,还是彩色的,怎么做到的呢?
武大源代码我简单看过,原理是类似的。
我做的视频的效果图(从视频截的图):
这里特别说明一下,黑底和白底,效果图有很大差别的,建议使用黑底,就是RGB(0,0,0)
设置背景色
原理很简单,说白了就是把一个视频抽分成n多个图片,比如一秒钟的视频拆出30份图片,再合成,那么这个导出视频就是三十帧,60就是六十,但是速度会受改变,这个自己去理解一下。
就是导出视频的帧率和速度取决于原视频,这个我不专业,简单说明。
拿到了几十张,甚至上百上千张这样的图片,把它们全体存放在old文件夹下。这时需要对每一张图片进行划分,例如64x64,128x128的网格状小正方形
每一块正方形中原本是图片,但是现在需要填充你所想要替换的文字,注意,这里是将原来色彩的图片调用方法替换成相同颜色的文字。
当然你也可以用图片的convert方法改成黑白色。
改完了的图片又是几百张上千张,我把它固定的集中在一个new文件夹下,供第三步的使用。
第三步的作用很简单了,就是将所有图片合成视频,例如90张的图片按三十帧合成,那么导出的视频就是3秒,按10帧合成就是九秒,当然这样会感到卡顿,速度变慢。
建议自己把帧率和速度一一对应,调试一下即可。
原理就是这样,其中一三步都可以用视频软件实现的,例如PR,AE,但是很费事,也比较烧电脑,既然用了pycharm就要用到底啊,全必须用python敲出来!!
********废话不多说,实施:
1.几个必要的包,Pillow,Pilow-PIL,opencv-python,os都必须提前下好导入。
2.在D盘根目录下新建一个photo文件夹,photo文件夹中再新建new和old两个文件夹,用于存放照片,最好这样命名,避免代码中路径的修改
3.去网上下载经典综艺体简体这个字体的TTF文件,也同样存放在photo文件夹下。*下载lianjie在代码注释里
注意,这里最好是下“经典综艺体”其他的字体测试时候可能会有bug
4.将需要做的视频放在pycharm项目根目录下(与.py文件同级),命名为1.mp4。
5.将程序分为三个模块,每次只执行一个模块,其余两个注释掉。
因为图片处理的速度比较慢,同时执行会因为目录中来不及产生需要的文件报错
6.建议帧率不要选择太高,还有视频不要选择太长,10几秒即可。不然导出的图片数量过大第二部上像素的过程会很缓慢。
7.几个特别注意的地方:注释中打叹号的地方需要仔细检查,特别是第二模块的for循环图片个数需要根据具体导出的图片数量修改。
'''
第一部分代码,首先执行。此时请注释掉:第二第三部分的所有代码,(一二三只能按顺序依次执行)!!!!!!!!!!!!!!!!!
'''
'''
第一部分:目的是将你准备好的视频素材,剪成n多张图片,存在D:/photo/old/文件夹下
'''
import cv2
import os #opencv和os,记得提前下载opencv-python(在控制台输入pip install opencv-python)
#要提取视频的文件名,隐藏后缀,例如视频素材是1.mp4,这里只需要保留'1'即可
sourceFileName='1'
#在这里通过代码把后缀接上,这一步不需要你去动
video_path = os.path.join("", "", sourceFileName+'.mp4')
times=0
#提取视频的频率,每2帧提取一个
frameFrequency=2
#输出图片到old文件夹下
outPutDirName='D:/photo/old/'
if not os.path.exists(outPutDirName):
#如果old文件夹不存在则创建目录
os.makedirs(outPutDirName)
camera = cv2.VideoCapture(video_path)
i=0
while True:
times+=1
res, image = camera.read()
if not res:
print('not res , not image')
break
if times%frameFrequency==0:
cv2.imwrite(outPutDirName + str(i)+'.jpg', image)
print(outPutDirName + str(i)+'.jpg')
#将每一帧分离出来的图片保存在文件夹内,从0.jpg,1.jpg......100.jpg按顺序排好
i+=1
print('图片提取结束')
camera.release()
'''
第二部分:此时请注释掉1,3部分的代码,(一二三只能按顺序依次执行,每次执行一个模块)!!!!!!!!!!!!!!!!!!!!!
'''
'''
第二部分:在导出的每一帧图片上,给每一块细小的像素,用文字替换原图
'''
from PIL import Image, ImageDraw, ImageFont #记得提前下载pillow或pillow-PIL
for i in range(100):#这里千万要注意改!,new文件夹里有多少张图片,这里就填多少!!!!!!!!!!!!!!!!!!!!!!!!!!!!
font_size = 12
text = "自定义你想要输出的文字"
img_path = "D:/photo/old/"+str(i)+".jpg"
img_raw = Image.open(img_path)
img_array = img_raw.load()
img_new = Image.new("RGB", img_raw.size, (0,0,0)) #背景色,默认为黑色0 0 0,可以调成白色255 255 255
draw = ImageDraw.Draw(img_new)
font = ImageFont.truetype('D:\photo\经典综艺体简.TTF', font_size)
#经典综艺体简.TTF,是一种字体,你也可以下载别的字体,放在这个文件夹里,注意改名!!!!!!!!!!!!!!!!!!!!
# 别的字体我试过,很多输出显示会有bug,建议下载这种字体#http://www.font5.com.cn/font_download.php?id=201&part=1239976947
def character_generator(text):
while True:
for i in range(len(text)):
yield text[i]
ch_gen = character_generator(text)
for y in range(0, img_raw.size[1], font_size):
for x in range(0, img_raw.size[0], font_size):
draw.text((x, y), next(ch_gen), font=font, fill=img_array[x, y], direction=None)
# img_new=img_new.convert("L") #特别注释,这句话的作用是把图像转换为黑白色,一般注释掉,默认输出彩色
img_new.convert('RGB').save("D://photo//new//"+str(i)+".jpg")
#执行完之后所有的"马赛克"图片就会在new文件夹里存放,按顺序排列
'''
第三部分:把第一二部分全部注释掉,(一二三只能按顺序依次执行,每次执行一个模块)!!!!!!!!!!!!!!!!!!!!!
'''
'''
第三部分:把几百张图片合成一个完整的视频,可以自己调试最适合的帧率
'''
import cv2 #同样需要导入cv2,请提前下载好
import os
im_dir='D:/photo/new'
video_dir = 'new.avi'
imglist = sorted(os.listdir(im_dir))
imglist.sort(key=lambda x: int(x[:-4]))
img = cv2.imread(os.path.join(im_dir,imglist[0]))
H, W, D = img.shape
print('height:' + str(H)+'--'+'width:'+str(W)+'--'+'depth:'+str(D))
fps = 24 #输出视频的帧率是24,这里可以修改视频帧率,自己摸索调出最适合的帧率,一般20-30即可
img_size = (W,H)
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
videoWriter = cv2.VideoWriter(video_dir, fourcc, fps, img_size)
for image in imglist:
img_name = os.path.join(im_dir, image)
frame = cv2.imread(img_name)
videoWriter.write(frame)
print('合成==>'+img_name)
videoWriter.release()
print('finish!')
#第三步没有什么需要注意的
#当看到finish!完成之后,去你的这个pycharm项目文件夹下找到视频new.avi即为导出的视频