Python抖音快手代码舞(字符舞)的实现方法


Posted in Python onFebruary 07, 2021

先上效果,视频敬上:

字符舞:

Python抖音快手代码舞(字符舞)的实现方法

代码舞

源代码:

video_2_code_video.py

import argparse
import os
import cv2
import subprocess
from cv2 import VideoWriter_fourcc
from 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文件,默认不保存

class Video2CodeVideo:
 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):
 if alpha == 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
 return self.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 = []
 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 += 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码进行上色
 for i 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
 if vc.isOpened():
  r, frame = vc.read()
  if not 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
 while r:
  cv2.imwrite(str(c) + '.jpg', frame)
  self.txt_2_image(str(c) + '.jpg') # 同时转换为ascii图
  r, frame = vc.read()
  c += 1
 os.chdir('..')
 return vc

 # 第二步,将字符图片合成新视频
 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"])
 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 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)

 # 第五步,如果没配置保留则清除过程文件
 def clean_cache_while_need(self):
 # 为了清晰+代码比较短,直接写成内部函数
 def remove_cache_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_cache_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
 # 为了清晰+代码比较短,直接写成内部函数
 def delete_middle_media_file():
  os.remove(self.config_dict["input_file"].split('.')[0] + '.mp3')
  os.remove(self.config_dict["input_file"].split('.')[0] + '.avi')
 # 如果没配置保留则清除过程文件
 if not self.config_dict["save_cache_flag"]:
  remove_cache_dir(self.config_dict["cache_dir"])
  delete_middle_media_file()

 # 程序主要逻辑
 def main_logic(self):
 # 第一步,将原视频转成字符图片
 vc = self.video_2_txt_jpg(self.config_dict["input_file"])
 # 获取原视频帧率
 fps = vc.get(cv2.CAP_PROP_FPS)
 # print(fps)
 vc.release()
 # 第二步,将字符图片合成新视频
 self.txt_jpg_2_video(self.config_dict["input_file"].split('.')[0], fps)
 print(self.config_dict["input_file"], self.config_dict["input_file"].split('.')[0] + '.mp3')
 # 第三步,从原视频中提取出背景音乐
 self.video_extract_mp3(self.config_dict["input_file"])
 # 第四步,将背景音乐添加到新视频中
 self.video_add_mp3(self.config_dict["input_file"].split('.')[0] + '.avi', self.config_dict["input_file"].split('.')[0] + '.mp3')
 # 第五步,如果没配置保留则清除过程文件
 self.clean_cache_while_need()

if __name__ == '__main__':
 obj = Video2CodeVideo()
 obj.main_logic()

运行环境:

操作系统:win10

版本:Python 3.8.4

依赖库:pip install opencv-python pillow

管理员权限安装,我的已安装过,显示这样:

Python抖音快手代码舞(字符舞)的实现方法

依赖应用: ffpmeg(下载直接解压、将bin目录加到PATH环境变量)

Python抖音快手代码舞(字符舞)的实现方法

小白式运行(大佬请装瞎):

将上面的源代码命名video_2_code_video.py,在同一目录下新建文件夹video:

Python抖音快手代码舞(字符舞)的实现方法

在video中放入要转换的原视频,命名test.mp4:

Python抖音快手代码舞(字符舞)的实现方法

打开Python3.8

Python抖音快手代码舞(字符舞)的实现方法

运行video_2_code_video.py,如下图显示表示正在运行:

Python抖音快手代码舞(字符舞)的实现方法

会产生一些中间文件诸如:

Python抖音快手代码舞(字符舞)的实现方法

Python抖音快手代码舞(字符舞)的实现方法

经过漫长的等待,终于得偿所愿:

Python抖音快手代码舞(字符舞)的实现方法

test-txt.mp4就是所要的代码舞啦:

Python抖音快手代码舞(字符舞)的实现方法

总结 

到此这篇关于Python抖音快手代码舞实现的文章就介绍到这了,更多相关Python抖音快手代码舞内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python排序方法实例分析
Apr 30 Python
python实现中文输出的两种方法
May 09 Python
python计算时间差的方法
May 20 Python
Python下的常用下载安装工具pip的安装方法
Nov 13 Python
深入解读Python解析XML的几种方式
Feb 16 Python
python爬取51job中hr的邮箱
May 14 Python
Python按行读取文件的实现方法【小文件和大文件读取】
Sep 19 Python
python爬虫获取京东手机图片的图文教程
Dec 29 Python
Python使用Pickle模块进行数据保存和读取的讲解
Apr 09 Python
简单了解python中的f.b.u.r函数
Nov 02 Python
django-csrf使用和禁用方式
Mar 13 Python
如何一键升级Python所有包
Nov 05 Python
Python图像处理之膨胀与腐蚀的操作
Feb 07 #Python
django inspectdb 操作已有数据库数据的使用步骤
Feb 07 #Python
python数据抓取3种方法总结
Feb 07 #Python
python 批量将中文名转换为拼音
Feb 07 #Python
如何用用Python将地址标记在地图上
Feb 07 #Python
python 三种方法提取pdf中的图片
Feb 07 #Python
Python 转移文件至云对象存储的方法
Feb 07 #Python
You might like
建立文件交换功能的脚本(一)
2006/10/09 PHP
php getimagesize 上传图片的长度和宽度检测代码
2010/05/15 PHP
Windows下利用Gvim写PHP产生中文乱码问题解决方法
2011/04/20 PHP
php中preg_match的isU代表什么意思
2015/10/01 PHP
javascript 鼠标滚轮事件
2009/04/09 Javascript
Javascript结合css实现网页换肤功能
2009/11/02 Javascript
JS获取时间的方法
2015/01/21 Javascript
jQuery制作可自定义大小的拼图游戏
2015/03/30 Javascript
AngularJS基础学习笔记之表达式
2015/05/10 Javascript
jQuery ztree实现动态树形多选菜单
2016/08/12 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
2016/09/05 Javascript
微信小程序实现默认第一个选中变色效果
2018/07/17 Javascript
JS如何获取地址栏的参数实例讲解
2018/10/06 Javascript
vue.config.js常用配置详解
2019/11/14 Javascript
python中pycurl库的用法实例
2014/09/30 Python
Python3指定路径寻找符合匹配模式文件
2015/05/22 Python
深入理解Python中各种方法的运作原理
2015/06/15 Python
在Linux系统上部署Apache+Python+Django+MySQL环境
2015/12/24 Python
使用python爬取B站千万级数据
2018/06/08 Python
Python for循环中的陷阱详解
2018/07/13 Python
解决pycharm py文件运行后停止按钮变成了灰色的问题
2018/11/29 Python
Python 保存加载mat格式文件的示例代码
2020/08/04 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
CSS3 制作旋转的大风车(充满童年回忆)
2013/01/30 HTML / CSS
CSS3制作炫酷的自定义发光文字
2016/03/28 HTML / CSS
推荐信格式范文
2014/05/09 职场文书
外贸业务员求职信
2014/06/16 职场文书
小学教师暑期培训方案
2014/08/28 职场文书
党旗在我心中演讲稿
2014/09/15 职场文书
党员对照检查材料思想汇报
2014/09/16 职场文书
2014年语文教研组工作总结
2014/12/06 职场文书
中小学生安全教育观后感
2015/06/17 职场文书
保护环境的宣传语
2015/07/13 职场文书
2016教师廉洁从教心得体会
2016/01/13 职场文书
golang json数组拼接的实例
2021/04/28 Golang
Spring boot实现上传文件到本地服务器
2022/08/14 Java/Android