脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - python将视频转换为全字符视频

python将视频转换为全字符视频

2021-06-20 00:45kongfu_cat Python

这篇文章主要为大家详细介绍了Python将视频转换为全字符视频,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

简介

如何简单的使用python来实现将一部视频转换为字符画视频的效果。
其实,大家都知道视频就是一帧一帧的图片构成的。  

python将视频转换为全字符视频

那么如今我们想要实现,将视频转换为字符视频,那么是不是可以认为只要将一部视频全部逐帧拆解成图片,然后采取和以前相同的将图片转换为字符画的算法即可。然后在将这些图片按照原先的视频的格式封装起来就可以了。

既然有了想法,那接下来,自然是开始实际开发了。

代码

以下是相关部分的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#-*- coding:utf-8 -*-
import argparse
import os
import cv2
import subprocess
from cv2 import videowriter,videowriter_fourcc,imread,resize
from pil import image, imagefont, imagedraw
#命令行输入参数处理
parser = argparse.argumentparser()
parser.add_argument('file')
parser.add_argument('-o','--output')
parser.add_argument('-f','--fps',type = float, default = 24)#帧
parser.add_argument('-s','--save',type = bool, nargs='?', default = false, const = true)
#是否保留cache文件,默认不保存
 
#获取参数
args = parser.parse_args()
input = args.file
output = args.output
save = args.save
fps = args.fps
#像素对应ascii码
 
ascii_char = list("$@b%8&wm#*oahkbdpqwmzo0qlcjuyxzcvunxrjft/\|()1{}[]?-_+~<>i!li;:oa+>!:+. ")
#ascii_char = list("mnhq$oc67+>!:-. ")
#ascii_char = list("mnhq$oc67)oa+>!:+. ")
 
#将像素转换为ascii码
def get_char(r,g,b,alpha = 256):
 if alpha == 0:
  return ''
 length = len(ascii_char)
 gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
 unit = (256.0+1)/length
 return ascii_char[int(gray/unit)]
 
#将txt转换为图片
def txt2image(file_name):
 im = image.open(file_name).convert('rgb')
 #gif拆分后的图像,需要转换,否则报错,由于gif分割后保存的是索引颜色
 raw_width = im.width
 raw_height = im.height
 width = int(raw_width/6)
 height = int(raw_height/15)
 im = im.resize((width,height),image.nearest)
 
 txt=""
 colors = []
 for i in range(height):
  for j in range(width):
   pixel = im.getpixel((j,i))
   colors.append((pixel[0],pixel[1],pixel[2]))
   if(len(pixel) == 4):
    txt += get_char(pixel[0],pixel[1],pixel[2],pixel[3])
   else:
    txt += get_char(pixel[0],pixel[1],pixel[2]) 
  txt += '\n'
  colors.append((255,255,255))
 
 im_txt = image.new("rgb",(raw_width,raw_height),(255,255,255))
 dr = imagedraw.draw(im_txt)
 #font = imagefont.truetype(os.path.join("fonts","汉仪楷体简.ttf"),18)
 font=imagefont.load_default().font
 
 x=y=0
 #获取字体的宽高
 font_w,font_h=font.getsize(txt[1])
 font_h *= 1.37 #调整后更佳
 #imagedraw为每个ascii码进行上色
 for i in range(len(txt)):
  if(txt[i]=='\n'):
   x+=font_h
   y=-font_w
  dr.text((y,x),txt[i],font = font, fill = colors[i])
  y+=font_w
 
 name = file_name
 print(name+' changed')
 im_txt.save(name)
#将视频拆分成图片
def video2txt_jpg(file_name):
 vc = cv2.videocapture(file_name)
 c=1
 if vc.isopened():
  r,frame = vc.read()
  if not os.path.exists('cache'):
   os.mkdir('cache')
  os.chdir('cache')
 else:
  r = false
 while r:
  cv2.imwrite(str(c)+'.jpg',frame)
  txt2image(str(c)+'.jpg')#同时转换为ascii图
  r,frame = vc.read()
  c += 1
 os.chdir('..')
 return vc
 
#将图片合成视频
def jpg2video(outfile_name,fps):
 fourcc = videowriter_fourcc(*"mjpg")
 
 images = os.listdir('cache')
 im = image.open('cache/'+images[0])
 vw = cv2.videowriter(outfile_name+'.avi',fourcc,fps,im.size)
 
 os.chdir('cache')
 for image in range(len(images)):
  #image.open(str(image)+'.jpg').convert("rgb").save(str(image)+'.jpg')
  frame = cv2.imread(str(image+1)+'.jpg')
  vw.write(frame)
  print(str(image+1)+'.jpg'+' finished')
 os.chdir('..')
 vw.release()
 
#递归删除目录
def remove_dir(path):
 if os.path.exists(path):
  if os.path.isdir(path):
   dirs = os.listdir(path)
   for d in dirs:
    if os.path.isdir(path+'/'+d):
     remove_dir(path+'/'+d)
    elif os.path.isfile(path+'/'+d):
     os.remove(path+'/'+d)
   os.rmdir(path)
   return
  elif os.path.isfile(path):
   os.remove(path)
  return
#调用ffmpeg获取mp3音频文件
def video2mp3(file_name):
 outfile_name = file_name.split('.')[0]+'.mp3'
 subprocess.call('ffmpeg -i '+file_name+' -f mp3 '+outfile_name,shell = true)
#合成音频和视频文件
def video_add_mp3(file_name,mp3_file):
 outfile_name = file_name.split('.')[0]+'-txt.mp4'
 subprocess.call('ffmpeg -i '+file_name+' -i '+mp3_file+' -strict -2 -f mp4 '+outfile_name,shell = true)
 
if __name__=='__main__':
 vc = video2txt_jpg(input)
 fps = vc.get(cv2.cap_prop_fps)#获取帧率
 vc.release()
 
 jpg2video(input.split('.')[0],fps)
 print(input,input.split('.')[0]+'.mp3')
 video2mp3(input)
 video_add_mp3(input.split('.')[0]+'.avi',input.split('.')[0]+'.mp3')
 
 if(not save):
  remove_dir("cache")
  os.remove(input.split('.')[0]+'.mp3')
  os.remove(input.split('.')[0]+'.avi')

流程图

这次python编程的流程图如下:

python将视频转换为全字符视频

注意事项

在编程的过程中有需要注意的几点:

  • 这次编程使用到了opencv库,需要安装
  • 帧率的获取可以通过这个函数——fps = vc.get(cv2.cap_prop_fps)
  • 合成后的视频是没有声音的,我们使用ffmpeg进行合成

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/kongfu_cat/article/details/79681719

延伸 · 阅读

精彩推荐