利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖

2024-02-16 19:30

本文主要是介绍利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

源码地址

原教程在这里

演示效果:(有点虚)

利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖

使用教程(源码在文章最后)

  1. 打开pyhton编译器安装opencv和Pillow库
  2. 把要进行字符串化的视频命名为input.mp4(或者在代码里修改进行字符串化的视频从input.mp4改为你的视频名)
  3. 运行代码,此时会有进度提示
  4. 找自己这个pyhton文件的位置会有一个video文件夹生成
  5. 完了,记得帮我点个赞或者收藏一下😳😳😳

你可能需要安装opencv和Pillow。如果没有这两个库,通常情况下本脚本会自动帮你安装。如果自动安装失败,请在cmd分别运行。

pip3 install opencv-python-headlesspip3 install Pillow

在这里插入图片描述

在这里插入图片描述

源代码

import sys
import os
import time
import shutil
from multiprocessing import Processtry:from PIL import Image, ImageFont, ImageDraw
except ImportError:os.system('pip3 install Pillow -i https://mirrors.aliyun.com/pypi/simple/')from PIL import Image, ImageFont, ImageDrawtry:import cv2from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize
except ImportError:os.system('pip3 install opencv-python-headless -i https://mirrors.aliyun.com/pypi/simple/')import cv2from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize# =========================
# coding:UTF-8
# 视频转字符画含音频version-2.1
# 参考1:https://blog.csdn.net/mp624183768/article/details/81161260
# 参考2:https://blog.csdn.net/qq_42820064/article/details/90958577
# 参考3:https://blog.csdn.net/zj360202/article/details/79026891
# =========================def get_char(r, g, b, alpha=256):ascii_char = list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ")# ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:oa+>!:+. ")if alpha == 0:return ''length = len(ascii_char)gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)unit = (256.0 + 1) / len(ascii_char)return ascii_char[int(gray / unit)]# 将视频转换为图片 并进行计数,返回总共生成了多少张图片!
def video_to_pic(vp):print('正在对视频进行逐帧切片,请稍候...')# vp = cv2.VideoCapture(video_path)number = 0if vp.isOpened():r, frame = vp.read()if not os.path.exists(sys.path[0] + '/cache_pic'):os.mkdir(sys.path[0] + '/cache_pic')os.chdir(sys.path[0] + '/cache_pic')else:r = Falsewhile r:number += 1cv2.imwrite(sys.path[0] + '/cache_pic/' + str(number) + '.jpg', frame)r, frame = vp.read()print('由视频一共生成了{}张图片!'.format(number))os.chdir(sys.path[0])# os.chdir("../../../Downloads")return numberdef img_to_char(image_path, raw_width, raw_height, task):width = int(raw_width / 6)height = int(raw_height / 15)os.chdir(sys.path[0])im = Image.open(image_path).convert('RGB')  # 必须以RGB模式打开im = im.resize((width, height), Image.NEAREST)txt = ''color = []for i in range(height):for j in range(width):pixel = im.getpixel((j, i))color.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'color.append((255, 255, 255))im_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255))dr = ImageDraw.Draw(im_txt)# font = ImageFont.truetype('consola.ttf', 10, encoding='unic') #改为这个字体会让图片比例改变font = ImageFont.load_default().fontx, y = 0, 0font_w, font_h = font.getsize(txt[1])font_h *= 1.37  # 调整字体大小for i in range(len(txt)):if (txt[i] == '\n'):x += font_hy = -font_wdr.text((y, x), txt[i], fill=color[i])y += font_wos.chdir(sys.path[0])# os.chdir('cache_char')im_txt.save(sys.path[0] + '/cache_char/' + str(task) + '.jpg')os.chdir(sys.path[0])# os.chdir("../../../Downloads")return 0# 使用多进程进行图片转字符画,number是cahce_pic中图片总数,start_number是该进程从第几副图开始做,end_number是该进程到第几副图结束。
class StarToCharMultiProcess(Process):def __init__(self, threadID, number, save_pic_path, start_number, end_number):super().__init__()self.threadID = threadIDself.number = numberself.save_pic_path = save_pic_pathself.start_number = start_numberself.end_number = end_numberdef run(self):print("开始进程:" + self.name)star_to_char2(self.number, self.save_pic_path, self.start_number, self.end_number)print(self.name + ":处理完成")print("退出进程:" + self.name)def star_to_char(number, save_pic_path):if not os.path.exists('cache_char'):os.mkdir('cache_char')img_path_list = [save_pic_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)]  # 生成目标图片文件的路径列表task = 0for image_path in img_path_list:img_width, img_height = Image.open(image_path).size  # 获取图片的分辨率task += 1img_to_char(image_path, img_width, img_height, task)print('{}/{} is finished.'.format(task, number))print('=======================')print('All images were finished!')print('=======================')return 0def star_to_char2(number, save_pic_path, start_number, end_number):os.chdir(sys.path[0])if not os.path.exists('cache_char'):try:os.mkdir('cache_char')except:passimg_path_list = [save_pic_path + r'/{}.jpg'.format(i) for i in range(start_number, end_number + 1)]  # 生成目标图片文件的路径列表task = start_number - 1for image_path in img_path_list:img_width, img_height = Image.open(image_path).size  # 获取图片的分辨率task += 1img_to_char(image_path, img_width, img_height, task)# print('{}/{} is finished.'.format(task, number))# print('=======================')# print('Finished!')# print('=======================')return 0def star_to_char_multi_process(number, save_pic_path, process_number):print("\n正在把图片转字符画,请稍候...")print("启动多进程处理:")processes = []for count in range(1, process_number + 1):if count == 1:start_number = 1end_number = start_number + number // process_numberelif count == process_number:start_number = end_number + 1end_number = numberelse:start_number = end_number + 1end_number = start_number + number // process_numberprocess = StarToCharMultiProcess(count, number, save_pic_path, start_number, end_number)process.start()processes.append(process)time.sleep(1)return processesdef process_bar(percent, start_str='', end_str='', total_length=0):# 进度条bar = ''.join("■ " * int(percent * total_length)) + ''bar = '\r' + start_str + bar.ljust(total_length) + ' {:0>4.1f}%|'.format(percent * 100) + end_strprint(bar, end='', flush=True)def jpg_to_video(char_image_path, FPS):print("\n开始合成视频")video_fourcc = VideoWriter_fourcc(*"MP42")  # 设置视频编码器,这里使用使用MP42编码器,可以生成更小的视频文件char_img_path_list = [char_image_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)]  # 生成目标字符图片文件的路径列表char_img_test = Image.open(char_img_path_list[1]).size  # 获取图片的分辨率os.chdir(sys.path[0])if not os.path.exists('video'):os.mkdir('video')video_writter = VideoWriter('video/new_char_video.avi', video_fourcc, FPS, char_img_test)sum = len(char_img_path_list)count = 0for image_path in char_img_path_list:img = cv2.imread(image_path)video_writter.write(img)end_str = '100%'count = count + 1process_bar(count / sum, start_str='', end_str=end_str, total_length=15)video_writter.release()print('\n')print('=======================')print('The video is finished!')print('=======================')def write_audio(video_path):# 加入音频cmd = 'ffmpeg -i ' + sys.path[0] + '/video/new_char_video.avi' + ' -i ' + video_path + ' -c copy -map 0 -map 1:1 -y -shortest ' + sys.path[0] + '/video/videoWithAudio.avi' + ' -y'os.system(cmd)# 压制成H.264 mp4格式cmd2 = 'ffmpeg -i ' + sys.path[0] + '/video/videoWithAudio.avi' + ' -c:v libx264 -strict -2 ' + sys.path[0] + '/video/finalOutput_VideoWithAudio.mp4' + ' -y'os.system(cmd2)def delete(path):try:shutil.rmtree(path)print('已删除:' + path)return 0except:print('删除' + path + '失败,可能是权限不足或目录不存在')return -1def input_process(default_video_path):video_path = default_video_pathwhile not os.path.exists(video_path):if len(sys.argv) == 2:video_path = sys.argv[1]elif len(sys.argv) == 1 and not os.path.exists(video_path):video_path = input('请输入要处理的视频名称:')video_path = sys.path[0] + '/' + video_pathreturn video_pathif __name__ == '__main__':# 各种参数video_path = sys.path[0] + '/input.mp4'  # 把input.mp4改成你的视频名字,注意前面的斜杠要保留save_pic_path = sys.path[0] + '/cache_pic'  # 别动save_charpic_path = sys.path[0] + '/cache_char'  # 别动processes_number = 8  # 使用多少个进程同时处理图片,通常不超过CPU线程数,可以自行设置video_path = input_process(video_path)# 处理vp = cv2.VideoCapture(video_path)number = video_to_pic(vp)FPS = vp.get(cv2.CAP_PROP_FPS)threads = star_to_char_multi_process(number, save_pic_path, processes_number)for thread in threads:thread.join()vp.release()jpg_to_video(save_charpic_path, FPS)delete(save_pic_path)delete(save_charpic_path)write_audio(video_path)  # 把原视频的音频复制到新视频中。需要安装ffmpeg,否则报错。没有ffmpeg请注释掉这行代码。

在这里插入图片描述
在这里插入图片描述

为什么报错?

在这里插入图片描述

你可能需要安装opencv和Pillow。如果没有这两个库,通常情况下本脚本会自动帮你安装。如果自动安装失败,请在cmd分别运行。

在这里插入图片描述

注意的事及其使用方法

你可能需要安装opencv和Pillow。如果没有这两个库,通常情况下本脚本会自动帮你安装。如果自动安装失败,请在cmd分别运行、。

pip3 install opencv-python-headlesspip3 install Pillow

支持常见的mp4、flv等格式。

需要在main函数中修改你的视频文件路径,默认视频文件名称为input.mp4,放在与本py文件相同的目录里。如果没有找到input.mp4,会自动询问你视频名称。

最简单的方法:将视频放置在py文件的文件夹下,并修改 video_path后的参数为你的视频名字即可运行。

此外还可以设置多进程处理图片,可自行修改进程数量。

if __name__ == '__main__':video_path = sys.path[0] + '/input.mp4'  # 把input.mp4改成你的视频名字,注意前面的斜杠要保留save_pic_path = sys.path[0] + '/cache_pic'  # 别动save_charpic_path = sys.path[0] + '/cache_char'  # 别动processes_number = 8  # 使用多少个进程同时处理图片,通常不超过CPU线程数,可以自行设置

为生成的视频添加原视频音轨并且压制为mp4需要预先安装好ffmpeg,如果没有安装ffmpeg,请注释掉或者删掉最后一行

write_audio(video_path)

最后附送一段舞蹈😍

利用Python程序生成字符画 跳舞

这篇关于利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/715494

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri