介绍Python的抖音快手字符舞


本文摘自php中文网,作者coldplay.xixi,侵删。

免费学习推荐:python视频教程

先上效果,视频敬上:

字符舞:

代码舞

源代码:

video_2_code_video.py

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

154

155

156

157

158

import argparseimport osimport cv2import subprocessfrom cv2 import VideoWriter_fourccfrom PIL import Image, ImageFont, ImageDraw# 命令行输入参数处理# aparser = argparse.ArgumentParser()# aparser.add_argument('file')# aparser.add_argument('-o','--output')# aparser.add_argument('-f','--fps',type = float,default= 24)#帧# aparser.add_argument('-s','--save',type = bool, nargs='?',default= False,const= True)# 是否保留Cache文件,默认不保存classVideo2CodeVideo:

    def __init__(self):

        self.config_dict = {

            # 原视频文件

            "input_file":"video/test.mp4",

            # 中间文件存放目录

            "cache_dir":"cache",

            # 是否保留过程文件。True--保留,False--不保留

            "save_cache_flag": False,

            # 使用使用的字符集

            "ascii_char_list": list("01B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:oa+>!:+. "),

        }

 

    # 第一步从函数,将像素转换为字符

    # 调用栈:video_2_txt_jpg -> txt_2_image -> rgb_2_char

    def rgb_2_char(self, r, g, b, alpha=256):

        ifalpha == 0:

            return''

        length = len(self.config_dict["ascii_char_list"])

        gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)

        unit = (256.0 + 1) / length       returnself.config_dict["ascii_char_list"][int(gray / unit)]

 

    # 第一步从函数,将txt转换为图片

    # 调用栈:video_2_txt_jpg -> txt_2_image -> rgb_2_char

    def txt_2_image(self, 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 = []

        fori in range(height):

            forj in range(width):

                pixel = im.getpixel((j, i))

                colors.append((pixel[0], pixel[1], pixel[2]))

                if(len(pixel) == 4):

                    txt += self.rgb_2_char(pixel[0], pixel[1], pixel[2], pixel[3])

                else:

                    txt += self.rgb_2_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码进行上色

        fori in range(len(txt)):

            if(txt[i] =='\n'):

                x += font_h

                y = -font_w            # self, xy, text, fill = None, font = None, anchor = None,

            # *args, ** kwargs

            dr.text((y, x), txt[i], fill=colors[i])

            # dr.text((y, x), txt[i], font=font, fill=colors[i])

            y += font_w

 

        name = file_name        #print(name +' changed')

        im_txt.save(name)

 

 

    # 第一步,将原视频转成字符图片

    # 调用栈:video_2_txt_jpg -> txt_2_image -> rgb_2_char

    def video_2_txt_jpg(self, file_name):

        vc = cv2.VideoCapture(file_name)

        c = 1

        ifvc.isOpened():

            r, frame = vc.read()

            ifnot os.path.exists(self.config_dict["cache_dir"]):

                os.mkdir(self.config_dict["cache_dir"])

            os.chdir(self.config_dict["cache_dir"])

        else:

            r = False

        whiler:

            cv2.imwrite(str(c) +'.jpg', frame)

            self.txt_2_image(str(c) +'.jpg')  # 同时转换为ascii图

            r, frame = vc.read()

            c += 1

        os.chdir('..')

        returnvc    # 第二步,将字符图片合成新视频

    def txt_jpg_2_video(self, outfile_name, fps):

        fourcc = VideoWriter_fourcc(*"MJPG")

 

        images = os.listdir(self.config_dict["cache_dir"])

        im = Image.open(self.config_dict["cache_dir"] +'/'+ images[0])

        vw = cv2.VideoWriter(outfile_name +'.avi', fourcc, fps, im.size)

 

        os.chdir(self.config_dict["cache_dir"])

        forimage 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 video_extract_mp3(self, file_name):

        outfile_name = file_name.split('.')[0] +'.mp3'

        subprocess.call('ffmpeg -i '+ file_name +' -f mp3 -y '+ outfile_name, shell=True)

 

    # 第四步,将背景音乐添加到新视频中

    def video_add_mp3(self, 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 -y '+ outfile_name, shell=True)

相关阅读 >>

详解神经网络理论基础及Python实现方法

Python数字类型有哪些

Python使用arrow库处理时间数据的示例详解

flask-migrate扩展的用法介绍(附代码)

map在Python中什么意思

Python3中时间处理与定时任务的方法介绍(附代码)

Python爬虫获取图片并下载保存至本地

Python中的计时器timeit的使用方法

r vs. Python数据分析详解

Python怎么实现马氏距离

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...