网上有好多照片转视频的那种电子相册制作, 由于作者的渣渣设计, 为了demo更加美观, 不得已抓包看了几个,发现有部分是能拿到设计者的设计素材的, 就厚脸皮的拿过来写写测试demo啦。
1, 素材转换
1.1, 由于很多素材都是图片, 我们需要把它转为视频
import cv2
fps = 15
def picToVideo(fileList, fps, out, size):
video = cv2.VideoWriter(out, cv2.VideoWriter_fourcc('I', '4', '2', '0'), fps, size)
for file in fileList:
img = cv2.imread(file)
video.write(img)
video.release()
if __name__ == '__main__':
fileList = []
for i in range(74):
fileList.append('./assets/asset31_%s.png' % (i))
picToVideo(fileList, fps, './asset31.avi', (720, 1064))
详细解释请点击: Python+Opencv实现把图片转为视频
1.2, 把视频转为遮罩层
因为我们要在视频上添加图片,所以要用遮罩层, 读取视频, 处理他的每一帧图片, 图片非有效的像素点转为黑色(0, 0,0), 有效像素点转为白色255, 255,255), 忘记的请看第二章 对遮罩层的讲解
def VideoMask(videoName, out, thresh, videoSize, fps):
cap = cv2.VideoCapture(videoName)
ret = True
i = 0
video = cv2.VideoWriter(out, cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'), fps, videoSize)
while cap.isOpened() and ret:
ret, frame = cap.read()
i = i + 1
print("has handle %s" % i)
if ret:
gray_freame= cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
for cols in range(frame.shape[0]):
for rows in range(frame.shape[1]):
if frame.item(cols, rows, 2) > thresh :
frame.itemset((cols, rows, 0), 255)
frame.itemset((cols, rows, 1), 255)
frame.itemset((cols, rows, 2), 255)
else:
frame.itemset((cols, rows, 0), 0)
frame.itemset((cols, rows, 1), 0)
frame.itemset((cols, rows, 2), 0)
video.write(frame)
# showim(frame)
video.release()
2, 编码过程
素材链接:pan.baidu.com/s/1FdibrQ1w… 提取码:fuun
原视频为1557975588645_album.mp4, 我们分析第三个片段(其他思路都一样)
处理这些视频我们要学会对视频分段处理,把一个完整的视频分割为一段一段来处理 第三段视频有 1, 纯色背景, 2, 中间的大白矩形, 3, 用户图片, 4, 用户图片的逐渐出现(遮罩层) 5, 花朵 6,花朵的遮罩层
当然每个人可以将视频的各个部分进行组合, 但是很明显的是 背景, 用户图片这些元素可以放在一起处理, 最后和花朵在合并在一起。
由于位置参数, 没有精准的量化, 以及时间的原因就没有把所有片段都做出来以及位置不是特别准确, 这些都要费时间微调数据 我这边就发出不太精准的数据。
# coding:utf-8
import cv2
from moviepy.editor import *
import numpy as np
from moviepy.video.tools.tracking import *
from moviepy.audio.fx import *
fps = 15
screen = (720, 1064)
def getBg(R, G, B):
bg = np.zeros((screen[1], screen[0], 3), np.uint8)
bg[:, :, 0] = np.zeros((1064, 720)) + R
bg[:, :, 1] = np.zeros((1064, 720)) + G
bg[:, :, 2] = np.zeros((1064, 720)) + B
bg = cv2.cvtColor(bg, cv2.COLOR_RGB2BGR)
return bg
def seg1(userPic):
screen_9 = (int(screen[0] * 0.8), int(screen[1] * 0.8))
# 纯色背景+中间白色边框
bgVideo = ImageClip(getBg(226, 222, 252)).set_duration(5).set_fps(fps)
whiteBlock1 = ImageClip(getBg(255, 255, 255)).set_start(0).set_duration(0.7).set_fps(fps).set_position(('center', 'center')).resize(lambda t: 0.1+ 0.7*(0.3 + t))
whiteBlock2 = ImageClip(getBg(255, 255, 255)).set_start(0.7).set_duration(4.5).set_fps(fps).set_position(
('center', 'center')).resize(0.8)
comp1 = CompositeVideoClip([bgVideo, whiteBlock1, whiteBlock2])
# 中间图片+遮罩层
picBg = ImageClip(getBg(255, 255, 255)).set_duration(5).set_fps(fps).resize(screen_9)
userPicVideo = ImageClip(userPic).resize(screen_9).set_start(0).set_duration(5).set_fps(fps).set_position(
('center', 'center'))
center1 = CompositeVideoClip([userPicVideo, picBg.set_mask(VideoFileClip('./mask.avi').resize(screen_9).to_mask())])
out1 = CompositeVideoClip([comp1, center1.set_start(1).set_position(('center', 'center'))])
# 将上述合成与动态花朵做合成
swing = VideoFileClip('./asset19.avi')
result = CompositeVideoClip([out1, swing.set_mask(swing.to_mask())]).set_duration(5)
return result
if __name__ == '__main__':
seg1_result = seg1('./assets/asset33.jpg')
seg1_result.write_videofile('./seg1_result.mp4')