視頻轉字元動畫-Python-60行代碼

来源:http://www.cnblogs.com/kirito-c/archive/2016/10/18/5971988.html
-Advertisement-
Play Games

"視頻轉字元動畫 Python 60行代碼" , 轉載請註明出處。 昨晚一朋友跟我說在網上看到了別人做的字元視頻,覺得很厲害,我於是也打算玩玩。今天中午花時間實現了這樣一個小玩意。 順便把過程記錄在這裡。 步驟 1. 把視頻的幀保存為圖片 2. 把圖片轉化為字元圖片 3. 按順序播放圖片 模塊 這個 ...


視頻轉字元動畫-Python-60行代碼, 轉載請註明出處。


昨晚一朋友跟我說在網上看到了別人做的字元視頻,覺得很厲害,我於是也打算玩玩。今天中午花時間實現了這樣一個小玩意。
順便把過程記錄在這裡。

步驟

  1. 把視頻的幀保存為圖片
  2. 把圖片轉化為字元圖片
  3. 按順序播放圖片

模塊

這個程式需要用到這樣幾個模塊:

  1. opencv #用來讀取視頻,讀取有些壓縮視頻可能還要安裝解碼器
  2. Pillow #圖像處理,本來opencv大概也可以做,但是我不太熟悉它,所以還是用pillow
  3. time.sleep() #用來調節播放速度

讀取視頻

首先需要安裝opencv模塊
pip install opencv-python

然後用這個程式把圖片提取出來

import numpy as np
import cv2

cap = cv2.VideoCapture('BadApple.mp4')

num = 0
while (cap.isOpened()):
    print('pic',num)
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imwrite("img%d.png" % num, frame)
    num += 1
print('finish')

逐行解釋:
2-3行:導入numpy和opencv模塊(雖然不知道為什麼要numpy,但是opencv官方文檔就這麼寫的,我也就抄了下來)
5行: 讀取視頻,BadApple.mp4(點擊下載)換成你需要轉換的視頻(有些格式的視頻可能需要安裝解碼器才能正常讀取)
8行: 沒有讀到視頻尾部前,cap.isOpend()會一直返回True
9行: 告訴你正在處理第幾張圖片
10行: cap.read() 逐幀讀取視頻,返回一個img對象。
11行: 顏色空間轉換,把彩圖變成灰度圖,你也可以去丟掉它,在轉字元時用彩色字元。
12行: 保存圖片

運行結束會提示"Done!",不出問題的話這時程式目錄內會出現幾千張圖片

圖片轉化為字元畫

首先安裝pillow圖形庫
pip install pillow

然後運行這個腳本把所有圖片轉化為字元畫

from PIL import Image

size = (64, 48)

def resize_pic(img):
    im = Image.open(img, 'r').convert("L")
    im = im.resize(size)
    return im

def pic_to_char(num):
    video = open("video.txt", "w")
    for i in range(num):
        im = resize_pic('img%d.png' % i)
        for y in range(size[1]):
            for x in range(size[0]):
                color = ' ' if im.getpixel((x, y))>210 else '* ' 
                video.write(color)
            video.write("\n")
        print(i)
video.close()
print('Done!')

逐行解釋:
1-3行: 導入pillow庫,size是轉化出的字元圖片的尺寸,註意一是控制在40-80內保證你的屏幕能完整地顯示圖片,二是比例要和原視頻一致。
5-9行: 得到一個圖片文件名,Image.open()讀取圖片,convert("L")把它轉換為灰度圖,由於之前讀取圖片時已經轉化了,你可以去掉它,寫在這裡只是說明還有第二種方法。
im.resize()把im尺寸轉為size,返迴轉化後對象

10-: pic_to_char()接受一個num參數,表示一共有多少張圖片,把轉換出的字元全部寫入一個'video.txt'文件。
im.getpixel()接受一個二元組(x,y),返回坐標為x,y的像素的顏色,因為這裡是灰度圖,所以返回值是一個整數。可以聯想到如果是RGB圖,會返回一個三元組。
210是灰度值,大於它的像素會被轉換為"* ",多一個空格的原因是字元界面行之間有間距,空格用於抵消這個行距,保持長寬比。
因為實例視頻對比非常鮮明,所以就只用兩種字元代表黑和白了。如果你需要更強表現力,可以多用幾個字元,甚至添加彩色字元。你可以自行修改這個部分。

播放字元視頻

我們把所有的圖片不作區分地寫入了video.txt,可是怎樣用這個文件顯示我們的字元畫呢?
前面已經知道我們的每張圖高度為48(在size里定義),那麼每次從文本中讀取48行顯示在字元界面上,然後游標移回到第一行行首,再次讀取48行顯示,新的字元會覆蓋原有的字元串,這樣的效果就是字元視頻了。
代碼如下

def gotoxy():
    pass

video = open(r"video.txt", "r")
num = 1
for line in video:
    print(line,end='')
    if num % size[1] == 0:
        sleep(0.005)
        gotoxy()
    num += 1

逐行解析:
1-3行:gotoxy()函數將游標移到行首,其實現後面再說
4- : 打開video.txt(這裡一定要輸入完整的路徑,不要像我這麼懶),迭代讀取並輸出每一行(由於文本內已經寫入了換行符,所以指定print以''空字元結尾),每輸出48行休眠0.005s,sleep()用於調節播放速度。休眠之後將游標移到行首,如此往複。

現在還有一個gotoxy()沒實現,本來打我算用curses模塊來做的,這樣會簡單不少。但是看了半小時文檔還是不太會用(勿噴),所以直接做了個c語言拓展,用c語言的windows.h 的函數實現了cmd字元界面的定位。但是這樣程式就變複雜了,畢竟還要自己寫c語言包裝。如果你會curses模塊,願意指點一二,請告訴我怎麼做。

先說好寫拓展比較複雜,所以我把它放在最後了。怕麻煩的可以直接下載我編譯好的文件(win64系統,其他平臺需要自己編譯),或者去研究一下curses,或者直接用c語言實現這個play()函數。
http://odxw2uear.bkt.clouddn.com/gotoxy.cp35-win_amd64.pyd
http://odxw2uear.bkt.clouddn.com/gotoxy-0.0.0-py3.5.egg-info
下載這兩個文件放到你的python/Lib/site-packages文件夾內,把上面的gotoxy()改為

import gotoxy.flush as flush()

def gotoxy():
    flush()

這樣,你解決了gotoxy()這個麻煩,在命令行界面運行python play.py你就可以得到這樣的成果。
效果請點這裡
總共不到六十行代碼。(c拓展不算)

p.s.其實完全不需要把圖片保存下來再轉字元串,這裡把代碼分成三個部分只是便於理解,你甚至都不需要把字元保存到video.txt文件中。把這三個部分整合到一起的過程就交給你了,少年!


c拓展

準備好接受包裝的衝擊了嗎?我們開始吧!

我的c源碼如下

#include <conio.h>
#include <stdio.h>
#include <windows.h>

int flush() //這個就是我們需要的函數,因為不知道取什麼名字好,隨便寫了個。
{
    //隱藏游標
    CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);

    //游標回到行首
    COORD pos = {0,0};
    HANDLE h0ut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition (h0ut, pos);
    return 0;
}

需要用到的就是這個函數,下麵是函數包裝部分,我也前天才學了一點點c包裝方法,寫得不好就別噴了~~


#include "Python.h" 
//封裝
static PyObject*
gotoxy_flush(PyObject *self, PyObject *args)
{
    return (PyObject*)Py_BuildValue("i", flush()); //雖然說完全不需要返回值,還是返回一個吧
};

static PyMethodDef
ExtestMethods[] = { //方法數組
    {"flush",gotoxy_flush,METH_VARARGS},
    {NULL}, //NULL結尾
};

static struct PyModuleDef Extestmodule = {
    PyModuleDef_HEAD_INIT,

    "gotoxy", //name of moudle
    "a test module", //Docs string(may be null)
    -1, //size of pre-interpreter state or -1
    ExtestMethods, //method table
};

//module initialization function
PyMODINIT_FUNC
PyInit_gotoxy(void){
    return PyModule_Create(&Extestmodule);
}

然後寫一個setup.py來編譯並安裝這個模塊,我就不解釋了,沒學過的可以先看看《python核心編程(3 rd)》瞭解一下包裝方法。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 多線程技術可以更好地利用系統資源,減少用戶的響應時間,提高系統的性能和效率,但同時也增加了系統的複雜性和運維難度,特別是在高併發、大壓力、高可靠性的項目中。線程資源的同步、搶占、互斥都需要慎重考慮,以避免產生性能損耗和線程死鎖。 建議118:不推薦覆寫start方法 多線程比較簡單的實現方式是繼承T ...
  • 來來來,來看這篇文章: http://www.cnblogs.com/biyeymyhjob/archive/2012/07/19/2598815.html ...
  • 在寫PHP程式時,經常要用到include或require包含其他文件,但是各文件里包含的文件多了之後,就會產生路徑問題。 如下目錄: <web>(網站根目錄) ├<A>文件夾 │ │ │ └1.php ├<B>文件夾 │ │ │ └2.php └index.php 現在根目錄下的index.php ...
  • 一、struts2的工作原理 上圖為struts整體結構。 1.客戶端初始化一個指向servlet的請求; 2.請求通過一系列過濾器(其中的ActionContextCleanUp為可選過濾器,對struts與其他框架集成有幫助),到達StrutsPrepareAndExecuteFilter過濾器 ...
  • #查看tomcat進程ps -ef | grep tomcat#殺死進程命令kill -9 進程號#實時查看日誌信息tail -f catalina.out實例:ln -s /home/gamestat /gamestatlinux下的軟鏈接類似於windows下的快捷方式ln -s a b 中的 ...
  • 20161013問題解析請點擊今日問題下方的“【Java每日一題】20161014”查看 今日問題:請問主程式輸出結果是?(點擊以下“【Java每日一題】20161014”查看昨天問題解析) 題目原發佈於公眾號、簡書:【Java每日一題】20161014,Java每日一題20161014 每日一題最 ...
  • 1,打開window->Preferences,彈出Preferences面板。搜索Text Editors。找到background color,去掉system default。如圖: 重點:色調85,飽和度123,亮度205 2,自動生成特定代碼 :window->preferences->j ...
  • python官網:python-2.7.12.amd64.msihttps://pypi.python.org/pypi/setuptools:setuptools-28.6.0.zipsetuptools-28.6.0>python setup.py installhttps://pypi.pyt ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...