100行代码让你的代码跳起舞(视频转字符画)

思路分析

    整体步骤分为三步:

  1. 对视频进行抽帧得到图片
  2. 对图片进行处理得到字符画
  3. 按照一定顺序和一定时间在终端打印字符画实现动画效果

最终效果

 

代码实现

  • 第一步视频抽帧

# 第一步视频抽帧
def chouzhen(video_path):
    # 保存图片的路径
    savedpath = video_path.split('.')[0] + '/'
    isExists = os.path.exists(savedpath)
    if not isExists:
        os.makedirs(savedpath)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(savedpath)
        os.makedirs(savedpath)
        # print('path of %s already exist and rebuild' % (savedpath))

    # 视频帧率12
    fps = 12
    # 保存图片的帧率间隔
    count = 3

    # 开始读视频
    videoCapture = cv2.VideoCapture(video_path)
    i = 0
    j = 0
    while True:
        success, frame = videoCapture.read()
        i += 1
        if (i % count == 0):
            # 保存图片
            j += 1
            savedname = video_path.split('\\')[-1].split('.')[0] + '_' + '%04d' % j + '.jpg'
            cv2.imwrite(savedpath + savedname, frame)
            # print('image of %s is saved' % (savedname))

        if not success:
            print('抽帧完成')
            break
  • 第二步 把抽帧得到的图片集转换为字符画集

# 第二步 把抽帧得到的图片全部转化为字符画
def pic2str(video_path):
    ascil_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    table = ('#8XOHLTI)i=+;:,. ')  # 对于灰度图像效果不错


    # 拿到保存图片的路径
    pics_path = video_path.split('.')[0]

    # 创建保存字符画的路径
    str_pic_path = video_path.split('.')[0] + '_str'
    isExists = os.path.exists(str_pic_path)
    if not isExists:
        os.makedirs(str_pic_path)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(str_pic_path)
        os.makedirs(str_pic_path)
        # print('path of %s already exist and rebuild' % (savedpath))

    pics = os.listdir(pics_path)
    for pic in pics:
        pic_path = pics_path + '\\' + pic
        str_pic_name = str_pic_path + '\\' + pic.split('.')[0] + '.txt'

        # 转换
        img = Image.open(pic_path)
        img = img.resize((300, 200))  # 转换图像大小 可以调整字符串图像的长和宽

        if img.mode != "L":  # 如果不是灰度图像,转换为灰度图像
            im = img.convert("L")
        a = img.size[0]
        b = img.size[1]

        f = open(str_pic_name, 'w+')  # 目标文本文件

        for i in range(1, b, 2):
            line = ('')
            for j in range(a):
                line += table[int((float(im.getpixel((j, i))) / 256.0) * len(table))]
            line += ("\n")
            f.write(line)
        f.close()

    print('字符画完成')
    return str_pic_path

这里转换函数返回了保存的字符画集路径,为下一步骤做准备。

  • 第三步 按照顺序在终端打印 实现动画效果

# 第三步 把字符画按照顺序动态打印 实现动画效果
def play_str(play_dir):
    strs = os.listdir(play_dir)
    for str_txt in strs:
        real_dir = play_dir + '\\' + str_txt
        with open(real_dir, 'r') as f:
            ret = f.read()
        print(ret)
        time.sleep(0.05)
        subprocess.call('cls', shell=True)
  • 注意点

  1.  在终端打印时要把终端字体设置小一点,这样才能看到整体效果。
  2. 如果效果还是不太好,可以在第1步骤调整抽帧帧数,第2步骤中调整字符画大小,还有第三步骤调整打印速度。

 

完整代码

# -*- coding:utf8 -*-
import subprocess
import time
import cv2
import os
import shutil
from PIL import Image


# 第一步视频抽帧
def chouzhen(video_path):
    # 保存图片的路径
    savedpath = video_path.split('.')[0] + '/'
    isExists = os.path.exists(savedpath)
    if not isExists:
        os.makedirs(savedpath)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(savedpath)
        os.makedirs(savedpath)
        # print('path of %s already exist and rebuild' % (savedpath))

    # 视频帧率12
    fps = 12
    # 保存图片的帧率间隔
    count = 3

    # 开始读视频
    videoCapture = cv2.VideoCapture(video_path)
    i = 0
    j = 0
    while True:
        success, frame = videoCapture.read()
        i += 1
        if (i % count == 0):
            # 保存图片
            j += 1
            savedname = video_path.split('\\')[-1].split('.')[0] + '_' + '%04d' % j + '.jpg'
            cv2.imwrite(savedpath + savedname, frame)
            # print('image of %s is saved' % (savedname))

        if not success:
            print('抽帧完成')
            break


# 第二步 把抽帧得到的图片全部转化为字符画
def pic2str(video_path):
    ascil_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    table = ('#8XOHLTI)i=+;:,. ')  # 对于灰度图像效果不错


    # 拿到保存图片的路径
    pics_path = video_path.split('.')[0]

    # 创建保存字符画的路径
    str_pic_path = video_path.split('.')[0] + '_str'
    isExists = os.path.exists(str_pic_path)
    if not isExists:
        os.makedirs(str_pic_path)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(str_pic_path)
        os.makedirs(str_pic_path)
        # print('path of %s already exist and rebuild' % (savedpath))

    pics = os.listdir(pics_path)
    for pic in pics:
        pic_path = pics_path + '\\' + pic
        str_pic_name = str_pic_path + '\\' + pic.split('.')[0] + '.txt'

        # 转换
        img = Image.open(pic_path)
        img = img.resize((300, 200))  # 转换图像大小 可以调整字符串图像的长和宽

        if img.mode != "L":  # 如果不是灰度图像,转换为灰度图像
            im = img.convert("L")
        a = img.size[0]
        b = img.size[1]

        f = open(str_pic_name, 'w+')  # 目标文本文件

        for i in range(1, b, 2):
            line = ('')
            for j in range(a):
                line += table[int((float(im.getpixel((j, i))) / 256.0) * len(table))]
            line += ("\n")
            f.write(line)
        f.close()

    print('字符画完成')
    return str_pic_path


# 第三步 把字符画按照顺序动态打印 实现动画效果
def play_str(play_dir):
    strs = os.listdir(play_dir)
    for str_txt in strs:
        real_dir = play_dir + '\\' + str_txt
        with open(real_dir, 'r') as f:
            ret = f.read()
        print(ret)
        time.sleep(0.05)
        subprocess.call('cls', shell=True)


# 程序入口
def run():
    # 开始
    # video_path = r'D:\pythoncode\app_shot_screens\video_chouzhen\dance.mp4' # 修改你要生成字符画的视频路径
    video_path = input('请输入要生成字符画的视频路径:') # 修改你要生成字符画的视频路径
    chouzhen(video_path)
    play_dir = pic2str(video_path)
    temp = input('转换完成 按任意键开始播放')
    play_str(play_dir)


if __name__ == '__main__':
    run()

 

"dw水调歌头"这个名词听起来像是一个特定的主题或者是某种特定的网页设计项目的名称。不过,没有一个公认的或者广泛被了解的叫做"dw水调歌头"的网页制作代码或框架。这可能是一个个人或特定团队的内部项目代号,或者是某种艺术项目。 如果你是在寻找如何制作一个以“水调歌头”为主题的网页代码,那么通常会涉及HTML来构建页面结构,CSS来设计页面样式,以及JavaScript来增加页面的交互性。以下是一个简单的网页结构示例: ```html <!DOCTYPE html> <html> <head> <title>水调歌头</title> <style> body { font-family: '宋体', sans-serif; text-align: center; padding: 50px; background-color: #f3f3f3; } h1 { color: #333; } .poem { text-align: left; margin: 20px auto; width: 50%; padding: 20px; border: 1px solid #ddd; background-color: #fff; } </style> </head> <body> <h1>水调歌头</h1> <div class="poem"> 明月几时有?把酒问青天。<br> 不知天上宫阙,今夕是何年。<br> 我欲乘风归去,又恐琼楼玉宇,高处不胜寒。<br> 起舞弄清影,何似在人间。<br> 朱阁,低绮户,照无眠。<br> 不应有恨,何事长向别时圆。<br> 人有悲欢离合,月有阴晴圆缺,此事古难全。<br> 但愿人长久,千里共婵娟。<br> </div> </body> </html> ``` 这个例子创建了一个简单的网页,包含了标题和一段古诗文字。如果你有更具体的需求或者想要实现特定的功能,请提供更多的信息。
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

honestman_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值