Python 圖片轉字元畫(實驗樓)
Python 圖片轉字元畫
一、實驗介紹
本實驗用 50 行 Python 程式碼完成圖片轉字元畫小工具。通過本實驗將學習到 Linux 命令列操作,Python 基礎,pillow 庫的使用,argparse 庫的使用。
1.1 實驗知識點
本節實驗中我們將實踐以下知識:
-
Linux 命令列操作
-
Python 基礎
-
pillow 庫的使用
-
argparse 庫的使用(參考教程)
1.2 實驗環境
-
python3.5
-
pillow-5.1.0
PIL 是一個 Python 影象處理庫,是本課程使用的重要工具,使用下面的命令來安裝 pillow(PIL)庫:
$ sudo pip3 install pillow
1.3 適合人群
本課程難度簡單,屬於 Python 基礎課程。
二、實驗原理
字元畫是一系列字元的組合,我們可以把字元看作是比較大塊的畫素,一個字元能表現一種顏色(暫且這麼理解吧),字元的種類越多,可以表現的顏色也越多,圖片也會更有層次感。
問題來了,我們是要轉換一張彩色的圖片,這麼多的顏色,要怎麼對應到單色的字元畫上去?這裡就要介紹灰度值的概念了。
灰度值:指黑白影象中點的顏色深度,範圍一般從0到255,白色為255,黑色為0,故黑白圖片也稱灰度影象
我們可以使用灰度值公式將畫素的 RGB 值對映到灰度值:
gray
這樣就好辦了,我們可以建立一個不重複的字元列表,灰度值小(暗)的用列表開頭的符號,灰度值大(亮)的用列表末尾的符號。
三、實驗步驟
在/home/shiyanlou/ 目錄下建立 ascii.py 檔案進行編輯:
$ cd /home/shiyanlou/
$ vim ascii.py
首先匯入必要的庫,argparse 庫是用來管理命令列引數輸入的
from PIL import Image
import argparse
下面是我們的字元畫所使用的字符集,一共有 70 個字元,字元的種類與數量可以自己根據字元畫的效果反覆除錯
ascii_char = list("[email protected]B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
下面是RGB值轉字元的函式:
def get_char(r,g,b,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
return ascii_char[int(gray/unit)]
下面是 ascii.py 的完整程式碼:
from PIL import Image
import argparse
#命令列輸入引數處理
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
ascii_char = list("[email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
# 將256灰度對映到70個字元上
def get_char(r,g,b,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
return ascii_char[int(gray/unit)]
if __name__ == '__main__':
im = Image.open(IMG)
im = im.resize((WIDTH,HEIGHT), Image.NEAREST)
txt = ""
for i in range(HEIGHT):
for j in range(WIDTH):
txt += get_char(*im.getpixel((j,i)))
txt += '\n'
print(txt)
#字元畫輸出到檔案
if OUTPUT:
with open(OUTPUT,'w') as f:
f.write(txt)
else:
with open("output.txt",'w') as f:
f.write(txt)
然後,我們還要從實驗樓下載用來測試的圖片:
$ wget http://labfile.oss.aliyuncs.com/courses/370/ascii_dora.png
ascii_dora.png
最後,使用剛剛編寫的 ascii.py 來將下載的 ascii_dora.png 轉換成字元畫。
$ python3 ascii.py ascii_dora.png
然後使用 vim 開啟 output.txt 檔案:
$ vim output.txt
你會看到下面的圖片:
提示:選單欄->編輯->首選項->外觀->字型 可以調節字型的大小。 下面圖片中的字號大小為 6。
注意,不同的環境中顯示的效果可能不盡相同
終端顯示的字型是不是等寬字型,終端顯示的行高和行寬,輸入輸出的影象寬高等等,這些都會影響顯示效果
如果你在實驗中遇到問題,可以通過下面的命令下載由實驗樓提供的程式碼以作參考。
$ wget http://labfile.oss.aliyuncs.com/courses/370/ascii.py
四、實驗小結
從實驗樓複製程式碼貼上過去是不能直接用的,因為搞亂了縮排。所以才出現以下問題,只要重新修改縮排就可以了。
還有注意的是:雖然報錯那裡,但實際上不止那裡,別的地方還有問題,需要從頭開始找。