Python -- 圖片轉(zhuǎn)字符畫

首先導(dǎo)入必要的庫限匣,argparse 庫是用來管理命令行參數(shù)輸入的

from PIL import Image
import argparse

首先導(dǎo)入必要的庫,argparse 庫是用來管理命令行參數(shù)輸入的

# 首先偿曙,構(gòu)建命令行輸入?yún)?shù)處理 ArgumentParser 實(shí)例
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) #輸出字符畫高

# 解析并獲取參數(shù)
args = parser.parse_args()

# 輸入的圖片文件路徑
IMG = args.file

# 輸出字符畫的寬度
WIDTH = args.width

# 輸出字符畫的高度
HEIGHT = args.height

# 輸出字符畫的路徑
OUTPUT = args.output

首先將 RGB 值轉(zhuǎn)為灰度值宵睦,然后使用灰度值映射到字符列表中的某個(gè)字符。

下面是我們的字符畫所使用的字符集群井,一共有 70 個(gè)字符状飞,為了方便寫入到實(shí)驗(yàn)環(huán)境中,可以使用實(shí)驗(yàn)環(huán)境右邊工具欄上的剪切板將以下代碼內(nèi)容拷貝到實(shí)驗(yàn)環(huán)境中书斜,注意需要使用右鍵復(fù)制和拷貝诬辈,不要使用 Ctrl-C/Ctrl-V 快捷鍵。字符的種類與數(shù)量可以自己根據(jù)字符畫的效果反復(fù)調(diào)試:

ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")

下面是 RGB 值轉(zhuǎn)字符的函數(shù)荐吉,注意 alpha 值為 0 的時(shí)候表示圖片中該位置為空白:

def get_char(r,g,b,alpha = 256):

    # 判斷 alpha 值
    if alpha == 0:
        return ' '

    # 獲取字符集的長度焙糟,這里為 70
    length = len(ascii_char)

    # 將 RGB 值轉(zhuǎn)為灰度值 gray,灰度值范圍為 0-255
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)

    # 灰度值范圍為 0-255样屠,而字符集只有 70
    # 需要進(jìn)行如下處理才能將灰度值映射到指定的字符上
    unit = (256.0 + 1)/length

    # 返回灰度值對應(yīng)的字符
    return ascii_char[int(gray/unit)]

完成上面的代碼之后穿撮,我們進(jìn)入到最后一個(gè)步驟昆咽,對圖片進(jìn)行處理矢洲。

這一個(gè)步驟我們放入到 if name == 'main': 代碼塊中(表示如果 ascii.py 被當(dāng)作 python 模塊 import 的時(shí)候缆巧,這部分代碼不會(huì)被執(zhí)行)宗弯。圖片的處理步驟如下:

首先使用 PIL 的 Image.open 打開圖片文件,獲得對象 im
使用 PIL 庫的 im.resize() 調(diào)整圖片大小對應(yīng)到輸出的字符畫的寬度和高度届慈,注意這個(gè)函數(shù)第二個(gè)參數(shù)使用 Image.NEAREST陵像,表示輸出低質(zhì)量的圖片呀伙。
遍歷提取圖片中每行的像素的 RGB 值知举,調(diào)用 getchar 轉(zhuǎn)成對應(yīng)的字符
將所有的像素對應(yīng)的字符拼接在一起成為一個(gè)字符串 txt
打印輸出字符串 txt
如果執(zhí)行時(shí)配置了輸出文件瞬沦,將打開文件將 txt 輸出到文件,如果沒有雇锡,則默認(rèn)輸出到 output.txt 文件
這個(gè)過程中需要注意的是調(diào)用 getchar 時(shí)候的參數(shù)是通過 PIL 庫的 getpixel 獲取的逛钻,見如下代碼:

char = get_char(*im.getpixel((j,i)))

其中 im.getpixel((j,i)) 獲取得到坐標(biāo) (j,i) 位置的 RGB 像素值(有的時(shí)候會(huì)包含 alpha 值),返回的結(jié)果是一個(gè)元組锰提,例如 (1,2,3) 或者 (1,2,3,0)曙痘。我們使用 * 可以將元組作為參數(shù)傳遞給 get_char芳悲,同時(shí)元組中的每個(gè)元素都對應(yīng)到 get_char 函數(shù)的每個(gè)參數(shù)。

該部分的代碼實(shí)現(xiàn)如下(注意 name 和 main 前后都是兩個(gè)下劃線):

if __name__ == '__main__':

    # 打開并調(diào)整圖片的寬和高
    im = Image.open(IMG)
    im = im.resize((WIDTH,HEIGHT), Image.NEAREST)

    # 初始化輸出的字符串
    txt = ""

    # 遍歷圖片中的每一行
    for i in range(HEIGHT):
        # 遍歷該行中的每一列
        for j in range(WIDTH):
            # 將 (j,i) 坐標(biāo)的 RGB 像素轉(zhuǎn)為字符后添加到 txt 字符串
            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)
完整代碼參考
# -*- coding=utf-8 -*-

from PIL import Image
import argparse

#命令行輸入?yún)?shù)處理
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) #輸出字符畫高

#獲取參數(shù)
args = parser.parse_args()

IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output

ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")

# 將256灰度映射到70個(gè)字符上
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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屡江,一起剝皮案震驚了整個(gè)濱河市芭概,隨后出現(xiàn)的幾起案子赛不,更是在濱河造成了極大的恐慌惩嘉,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踢故,死亡現(xiàn)場離奇詭異文黎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)殿较,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門耸峭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淋纲,你說我怎么就攤上這事劳闹。” “怎么了洽瞬?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵本涕,是天一觀的道長。 經(jīng)常有香客問我伙窃,道長菩颖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任为障,我火速辦了婚禮晦闰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳍怨。我一直安慰自己呻右,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布鞋喇。 她就那樣靜靜地躺著声滥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪确徙。 梳的紋絲不亂的頭發(fā)上醒串,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音鄙皇,去河邊找鬼芜赌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伴逸,可吹牛的內(nèi)容都是我干的缠沈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼洲愤!你這毒婦竟也來了颓芭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤柬赐,失蹤者是張志新(化名)和其女友劉穎亡问,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肛宋,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡州藕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酝陈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片床玻。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沉帮,靈堂內(nèi)的尸體忽然破棺而出锈死,到底是詐尸還是另有隱情,我是刑警寧澤穆壕,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布待牵,位于F島的核電站,受9級特大地震影響粱檀,放射性物質(zhì)發(fā)生泄漏洲敢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一茄蚯、第九天 我趴在偏房一處隱蔽的房頂上張望压彭。 院中可真熱鬧,春花似錦渗常、人聲如沸壮不。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽询一。三九已至,卻和暖如春癌椿,著一層夾襖步出監(jiān)牢的瞬間健蕊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工踢俄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缩功,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓都办,卻偏偏與公主長得像嫡锌,于是被迫代替她去往敵國和親虑稼。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容