Python
圖檔轉字元畫
一、實驗說明
1. 環境登入
無需密碼自動登入,
2. 環境介紹
本實驗環境采用帶桌面的UbuntuLinux環境,實驗中會用到桌面上的程式:
LX終端(LXTerminal):Linux指令行終端,打開後會進入Bash環境,可以使用Linux指令
3. 環境使用
使用GVim編輯器輸入實驗所需的代碼及檔案,使用LX終端(LXTerminal)運作所需指令進行操作。
完成實驗後可以點選桌面上方的“實驗截圖”儲存并分享實驗結果到微網誌,向好友展示自己的學習進度。實驗樓提供背景系統截圖,可以真實有效證明您已經完成了實驗。
實驗記錄頁面可以在“我的首頁”中檢視,其中含有每次實驗的截圖及筆記,以及每次實驗的有效學習時間(指的是在實驗桌面内操作的時間,如果沒有操作,系統會記錄為發呆時間)。這些都是您學習的真實性證明。
二、實驗内容
安裝pillow(PIL)庫:
$ sudo apt-getinstall python-dev
$ sudo apt-getinstall libtiff5-dev libjpeg8-dev zlib1g-dev \
libfreetype6-devliblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk
$ sudo pip installpillow
今天我們要做的是圖檔轉字元畫!
别慌!這是手工做的,我們這個做不了那麼好。
我們做的是這一類字元畫!
才幾行代碼,哪可能做成這種效果。
别急别急,這裡隻負責講解原理與生成字元,至于顯示效果,那還要看你顯示用的媒介怎麼樣了,像是字元是不是等寬啦,行高和行寬是不是相等啦,螢幕夠不夠大,夠不夠亮,夠不夠有型都可能是影響觀賞效果的因素呢。
開始碼代碼
首先擷取實驗用圖檔
wgethttp://labfile.oss.aliyuncs.com/courses/370/ascii_dora.png
建立ascii.py
檔案進行編輯
$ vi ascii.py
導入必要的庫
from PIL importImage
import argparse
一張圖檔從圖像到字元不是一蹴而就的,需要經過很多步驟,光看着可能沒什麼頭緒,先從成品上着手,成品是一系列字元的組合,我們可以把字元看作是比較大塊的像素,一個字元能表現一種顔色(暫且這麼了解吧),字元的種類越多,可以表現的顔色也越多,圖檔也會更有層次感,下面是我們選擇的字元集。
ascii_char =list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'.")
沒有自己用手去數吧?告訴你,一共有70
個字元,當然也不是字元越多越好,具體還得看選擇的圖檔,自己反複嘗試效果。
問題來了,我們是要轉換一張彩色的圖檔,這麼這麼多的顔色,要怎麼對應到字元上去?這裡就要介紹灰階值的概念了。
灰階值:指黑白圖像中點的顔色深度,範圍一般從0到255,白色為255,黑色為0,故黑白圖檔也稱灰階圖像
這樣就好辦了,灰階值大的用清單開頭的符号,灰階值小的用清單末尾的符号。
灰階值公式
灰階值=
0.2126 * r + 0.7152 * g + 0.0722 * b
先完成RGB值轉字元的函數:
defget_char(r,b,g,alpha = 256):
if alpha == 0:
return ' '
length =len(ascii_char)
gray =int(0.2126 * r + 0.7152 * g + 0.0722 * b)
unit = (256.0 +1)/length
returnascii_char[int(gray/unit)]
完整參考代碼:
#指令行輸入參數處理
parser =argparse.ArgumentParser()
parser.add_argument('file') #輸入檔案
parser.add_argument('-o','--output') #輸出檔案
parser.add_argument('--width',type = int, default = 80) #輸出字元畫寬
parser.add_argument('--height',type = int, default = 80) #輸出字元畫高
#擷取參數
args =parser.parse_args()
IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output
# 将256灰階映射到70個字元上
if __name__ =='__main__':
im =Image.open(IMG)
im =im.resize((WIDTH,HEIGHT), Image.NEAREST)
txt = ""
for i inrange(HEIGHT):
for j inrange(WIDTH):
txt +=get_char(*im.getpixel((j,i)))
txt += '\n'
print txt
#字元畫輸出到檔案
if OUTPUT:
withopen(OUTPUT,'w') as f:
f.write(txt)
else:
withopen("output.txt",'w') as f:
關鍵步驟除了那一步就沒有了(攤手)
argparse是一個管理指令行參數輸入的小工具
運作代碼檢視效果吧
$ python ascii.py imgfile