利用Python和C#实现字符视频

一、准备

我们使用PythonC#
先确保安装了opencvpillow

pip install opencv-python
pip install pillow

二、 处理视频

将视频逐帧转换为图片,然后逐张读入,修改大小为64×48,再转换为灰度图,然后二值化保存

import cv2
import numpy as np
from PIL import Image

#高度48 宽度64
H = 48
W = 64

#总帧数
cnt = 0

print("Char video maker by Azure99\nPress Enter to continue")
input()

print("Reading video")
video = cv2.VideoCapture("video.flv")
while video.isOpened() :
    print("img%d" % cnt)
    r, img = video.read();
    try :
        gary = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    except :
        break
    cv2.imwrite("png\\%d.png" % cnt, img)
    cnt += 1

videoData = open("video.txt", "w")

#逐帧转换为字符图
for i in range(cnt):
    print("frame%d" % i)
    #读入图片并修改大小, 再转换为灰度图
    img = Image.open("png\\%d.png" % i, "r").resize((W, H)).convert("L")
    for Y in range(H):
        for X in range(W):
            pixel = img.getpixel((X, Y))
            #二值化
            if pixel < 200:
                videoData.write(" #")
            else :
                videoData.write("  ")
        videoData.write("\n")

videoData.close()
print("All done!Now you can move video.txt to C# Player folder")

三、编写播放器

以48行为一帧,逐帧播放,并适当暂停
优化:
1.在播放前全部读入数据,并以每48行为单位保存在数组中
2.输出一帧时不要清屏,而是将光标移到开头,重新输出

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;

namespace Player
{
    class Program
    {
        private const int HEIGHT = 48;//每帧高度

        private static string[] frames;
        static void Main(string[] args)
        {
            Console.WriteLine("\t\tReading video...\n\n");

            ReadVideo();

            Console.WriteLine("\t\tChar video player by Azure99\n\t\tPress any key to play");
            Console.ReadKey();

            PlayVideo();
        }

        private static void ReadVideo()
        {
            StreamReader sr = new StreamReader("video.txt", Encoding.Default);
            List<string> framesList = new List<string>();

            while (!sr.EndOfStream)
            {
                StringBuilder sb = new StringBuilder();
                for(int i=0; i<HEIGHT; i++)//48行为一帧
                {
                    sb.Append(sr.ReadLine() + "\n");
                }
                framesList.Add(sb.ToString());
            }

            frames = framesList.ToArray();
        }

        private static void PlayVideo()
        {
            Console.Clear();
            for (int i = 0; i < frames.Length; i++)
            {
                //不要清屏, 将光标移到0, 0
                Console.CursorLeft = 0;
                Console.CursorTop = 0;
                Console.Write(frames[i]);
                Thread.Sleep(30);//根据机器配置, 调整暂停时间
            }
        }
    }
}

Azure99

大二蒟蒻,喜欢折腾vps、玩机,偶尔写写代码

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注