1. 程式人生 > >Python 圖片轉字元畫(實驗樓)

Python 圖片轉字元畫(實驗樓)

Python 圖片轉字元畫

一、實驗介紹

本實驗用 50 行 Python 程式碼完成圖片轉字元畫小工具。通過本實驗將學習到 Linux 命令列操作,Python 基礎,pillow 庫的使用,argparse 庫的使用。

1.1 實驗知識點

本節實驗中我們將實踐以下知識:

  1. Linux 命令列操作

  2. Python 基礎

  3. pillow 庫的使用

  4. 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

0.2126 * r + 0.7152 * g + 0.0722 * b

這樣就好辦了,我們可以建立一個不重複的字元列表,灰度值小(暗)的用列表開頭的符號,灰度值大(亮)的用列表末尾的符號

三、實驗步驟

/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

四、實驗小結

從實驗樓複製程式碼貼上過去是不能直接用的,因為搞亂了縮排。所以才出現以下問題,只要重新修改縮排就可以了。

還有注意的是:雖然報錯那裡,但實際上不止那裡,別的地方還有問題,需要從頭開始找。