如何使用 Python 將圖片變?yōu)樽址哪?/h1>
我們先來(lái)看一下,小帥b原本的頭像是這樣的:

用 Python 寫(xiě)的腳本轉(zhuǎn)一下,就變成這樣了:

也就是說(shuō),將圖片中的輪廓,用你喜歡的字符代替,是不是有點(diǎn)裝逼了:

這是如何實(shí)現(xiàn)呢?接下來(lái)就是:
學(xué)習(xí) Python 的正確姿勢(shì)
我們知道,每張圖片都是由一個(gè)個(gè)像素組成的,而你在手機(jī)上之所以可以看到五顏六色的圖片,是因?yàn)橛屑t綠藍(lán)三原色,它們可以組合成無(wú)數(shù)種顏色,而我們常見(jiàn)的顯示器用的就是 RGB 的顏色標(biāo)準(zhǔn),不同的 RGB 值代表不同的顏色強(qiáng)度,這個(gè)值在 0 到 255 之間。

其實(shí)我們想要讓圖片使用字符替換,并不需要那么多顏色,所以我們可以把圖片轉(zhuǎn)化為灰度圖像,這樣它就只剩下強(qiáng)度不同的黑與白了,這時(shí)候,我們只需要通過(guò)顏色的灰度值去區(qū)分就可以得到需要替換字符的地方。
也就是說(shuō)我們可以獲取一張圖片的所有像素,而每個(gè)像素都有它特有的灰度值,從 0----->255 表示從最黑到最白,那么我們只要準(zhǔn)備 256 個(gè)字符,把字符替換成灰度值,接著再輸出就行了。

因?yàn)榛叶葓D像只是黑白強(qiáng)度不同,所以我們并不需要細(xì)致到每一個(gè)具體的數(shù)值,可以把 0 ----> 255 拆分一下,比如每 25 個(gè)灰度值代表一種強(qiáng)度:
0--->25 ?? ? ? 白? ? ? 對(duì)應(yīng)字符a
25--->50? ? ? 淺灰? ??對(duì)應(yīng)字符b
50--->75? ? ? 灰? ? ? ?對(duì)應(yīng)字符c
... ??????????越來(lái)越灰? ?對(duì)應(yīng)字符d
225--->250? ?黑? ? ? ?對(duì)應(yīng)字符e
我們可以在這每個(gè)區(qū)間里定義一個(gè)字符,這時(shí)候只要判斷像素的灰度值,看看這個(gè)值在什么區(qū)間,對(duì)應(yīng)替換相應(yīng)的字符就可以了。
比如 a 這個(gè)字符對(duì)應(yīng)的是?0--->25 的灰度值區(qū)間,如果我們獲取到圖片的某一個(gè)像素的灰度值為 24 ,那么就將這個(gè)像素替換為a。
事就是這么個(gè)事,我們還是來(lái)用代碼體現(xiàn)一下會(huì)比較清晰。
0x00 | 定義字符串列表
定義一個(gè)字符串列表,我們將灰度值以 25 為單位進(jìn)行拆分,那么這個(gè)列表就需要有 11 個(gè)字符:

0x01 |?獲取圖片
想要通過(guò)命令直接獲取圖片的路徑,可以用 sys 模塊中的 argv 屬性,從?argv[1] 中可以獲取到使用 Python 命令攜帶的參數(shù):

0x02 |?圖片等比縮放
我們可以自己定義一下要輸出的字符圖片尺寸。通過(guò) Pillow 庫(kù)打開(kāi)圖片,等比例縮放:


比如我們希望輸出的字符圖片寬度是 100 ,那么就先獲取下原圖的寬高,計(jì)算下寬高比,然后得出新圖的寬高,生成新的圖片:

0x03 |?圖片轉(zhuǎn)成灰度
將圖片轉(zhuǎn)化為灰度很簡(jiǎn)單,調(diào)用 convert 方法就可以了:


0x04 | 獲取圖片的像素
可以通過(guò) image.getdata 來(lái)獲取圖片的所有像素灰度值:

可以打印看看這些像素值:

運(yùn)行一下是這樣子的:

(密集恐懼的不要點(diǎn)看)
是的,接下來(lái)我們就根據(jù)這些值替換字符。
0x05?| 替換字符
我們剛說(shuō)了,將灰度值以 25 為單位區(qū)分,所以我們可以通過(guò)像素的值除以 25 ,得到的就是我們剛剛定義 chars 列表的 index ,將 index 對(duì)應(yīng)的這些字符拼起來(lái)就可以了:

將剛剛獲取的像素替換成字符,打印一下:

我們運(yùn)行下:

我們剛剛定義的列表是這樣的:

而剛剛獲取的圖片像素值 255 是最多的,所以替換得到的 chars[10]?也就最多,不過(guò)為啥現(xiàn)在得到的結(jié)果亂七八糟呢?
0x06?| 結(jié)構(gòu)化字符
這是因?yàn)槲覀儎倓偪s放了圖片的寬高,輸出的字符應(yīng)該要對(duì)應(yīng)相應(yīng)的寬高,所以需要先獲取一下剛剛的字符長(zhǎng)度,接著循環(huán)它,以縮放后的寬作為步長(zhǎng),這樣得到的列表中的每個(gè)元素都是固定寬度的字符,接著就可以通過(guò) join 將列表轉(zhuǎn)化為字符串,每一行都鋪上相應(yīng)的字符:

現(xiàn)在再來(lái)運(yùn)行一波:

是不是有點(diǎn)內(nèi)味了,當(dāng)然,圖片的縮放比可以根據(jù)圖片再調(diào)調(diào),比如我們?cè)谟?jì)算縮放后的高度給它 × 個(gè) 0.66 看看:

再運(yùn)行一下:

是不是稍微舒服點(diǎn)了?
ok,以上。
部分代碼參考至:
https://github.com/RameshAditya/asciify/blob/master/asciify.py
本篇所涉及的完整代碼可在公眾號(hào)后臺(tái)發(fā)送 2 獲取,主要還是給你分享下思路,希望對(duì)你有幫助,那么我們下回見(jiàn),peace!
相關(guān)

掃一掃
學(xué)習(xí) Python 沒(méi)煩惱
小彩蛋(橫屏才能看到哦!)
........................................
........................................
........................................
........................................
..............66.....66.................
...........66.66.....66.................
...........66.66.6666666666.............
...........66.66.66..66..66.............
...........66.66.66..66..66.............
...........66.66.66..66..66.............
...........66.66.66..66..66.............
.............666.66..66..66.............
.............66..66..666666.............
............666......66.................
...........666.......66.................
........................................
........................................
........................................
........................................
........................................
瀏覽
50
我們先來(lái)看一下,小帥b原本的頭像是這樣的:

用 Python 寫(xiě)的腳本轉(zhuǎn)一下,就變成這樣了:

也就是說(shuō),將圖片中的輪廓,用你喜歡的字符代替,是不是有點(diǎn)裝逼了:

這是如何實(shí)現(xiàn)呢?接下來(lái)就是:
學(xué)習(xí) Python 的正確姿勢(shì)
我們知道,每張圖片都是由一個(gè)個(gè)像素組成的,而你在手機(jī)上之所以可以看到五顏六色的圖片,是因?yàn)橛屑t綠藍(lán)三原色,它們可以組合成無(wú)數(shù)種顏色,而我們常見(jiàn)的顯示器用的就是 RGB 的顏色標(biāo)準(zhǔn),不同的 RGB 值代表不同的顏色強(qiáng)度,這個(gè)值在 0 到 255 之間。

其實(shí)我們想要讓圖片使用字符替換,并不需要那么多顏色,所以我們可以把圖片轉(zhuǎn)化為灰度圖像,這樣它就只剩下強(qiáng)度不同的黑與白了,這時(shí)候,我們只需要通過(guò)顏色的灰度值去區(qū)分就可以得到需要替換字符的地方。
也就是說(shuō)我們可以獲取一張圖片的所有像素,而每個(gè)像素都有它特有的灰度值,從 0----->255 表示從最黑到最白,那么我們只要準(zhǔn)備 256 個(gè)字符,把字符替換成灰度值,接著再輸出就行了。

因?yàn)榛叶葓D像只是黑白強(qiáng)度不同,所以我們并不需要細(xì)致到每一個(gè)具體的數(shù)值,可以把 0 ----> 255 拆分一下,比如每 25 個(gè)灰度值代表一種強(qiáng)度:
0--->25 ?? ? ? 白? ? ? 對(duì)應(yīng)字符a
25--->50? ? ? 淺灰? ??對(duì)應(yīng)字符b
50--->75? ? ? 灰? ? ? ?對(duì)應(yīng)字符c
... ??????????越來(lái)越灰? ?對(duì)應(yīng)字符d
225--->250? ?黑? ? ? ?對(duì)應(yīng)字符e
我們可以在這每個(gè)區(qū)間里定義一個(gè)字符,這時(shí)候只要判斷像素的灰度值,看看這個(gè)值在什么區(qū)間,對(duì)應(yīng)替換相應(yīng)的字符就可以了。
比如 a 這個(gè)字符對(duì)應(yīng)的是?0--->25 的灰度值區(qū)間,如果我們獲取到圖片的某一個(gè)像素的灰度值為 24 ,那么就將這個(gè)像素替換為a。
事就是這么個(gè)事,我們還是來(lái)用代碼體現(xiàn)一下會(huì)比較清晰。
0x00 | 定義字符串列表
定義一個(gè)字符串列表,我們將灰度值以 25 為單位進(jìn)行拆分,那么這個(gè)列表就需要有 11 個(gè)字符:

0x01 |?獲取圖片
想要通過(guò)命令直接獲取圖片的路徑,可以用 sys 模塊中的 argv 屬性,從?argv[1] 中可以獲取到使用 Python 命令攜帶的參數(shù):

0x02 |?圖片等比縮放
我們可以自己定義一下要輸出的字符圖片尺寸。通過(guò) Pillow 庫(kù)打開(kāi)圖片,等比例縮放:


比如我們希望輸出的字符圖片寬度是 100 ,那么就先獲取下原圖的寬高,計(jì)算下寬高比,然后得出新圖的寬高,生成新的圖片:

0x03 |?圖片轉(zhuǎn)成灰度
將圖片轉(zhuǎn)化為灰度很簡(jiǎn)單,調(diào)用 convert 方法就可以了:


0x04 | 獲取圖片的像素
可以通過(guò) image.getdata 來(lái)獲取圖片的所有像素灰度值:

可以打印看看這些像素值:

運(yùn)行一下是這樣子的:

是的,接下來(lái)我們就根據(jù)這些值替換字符。
0x05?| 替換字符
我們剛說(shuō)了,將灰度值以 25 為單位區(qū)分,所以我們可以通過(guò)像素的值除以 25 ,得到的就是我們剛剛定義 chars 列表的 index ,將 index 對(duì)應(yīng)的這些字符拼起來(lái)就可以了:

將剛剛獲取的像素替換成字符,打印一下:

我們運(yùn)行下:

我們剛剛定義的列表是這樣的:

而剛剛獲取的圖片像素值 255 是最多的,所以替換得到的 chars[10]?也就最多,不過(guò)為啥現(xiàn)在得到的結(jié)果亂七八糟呢?
0x06?| 結(jié)構(gòu)化字符
這是因?yàn)槲覀儎倓偪s放了圖片的寬高,輸出的字符應(yīng)該要對(duì)應(yīng)相應(yīng)的寬高,所以需要先獲取一下剛剛的字符長(zhǎng)度,接著循環(huán)它,以縮放后的寬作為步長(zhǎng),這樣得到的列表中的每個(gè)元素都是固定寬度的字符,接著就可以通過(guò) join 將列表轉(zhuǎn)化為字符串,每一行都鋪上相應(yīng)的字符:

現(xiàn)在再來(lái)運(yùn)行一波:

是不是有點(diǎn)內(nèi)味了,當(dāng)然,圖片的縮放比可以根據(jù)圖片再調(diào)調(diào),比如我們?cè)谟?jì)算縮放后的高度給它 × 個(gè) 0.66 看看:

再運(yùn)行一下:

是不是稍微舒服點(diǎn)了?
ok,以上。
部分代碼參考至:
https://github.com/RameshAditya/asciify/blob/master/asciify.py
本篇所涉及的完整代碼可在公眾號(hào)后臺(tái)發(fā)送 2 獲取,主要還是給你分享下思路,希望對(duì)你有幫助,那么我們下回見(jiàn),peace!
相關(guān)

掃一掃
學(xué)習(xí) Python 沒(méi)煩惱
小彩蛋(橫屏才能看到哦!)
........................................
........................................
........................................
........................................
..............66.....66.................
...........66.66.....66.................
...........66.66.6666666666.............
...........66.66.66..66..66.............
...........66.66.66..66..66.............
...........66.66.66..66..66.............
...........66.66.66..66..66.............
.............666.66..66..66.............
.............66..66..666666.............
............666......66.................
...........666.......66.................
........................................
........................................
........................................
........................................
........................................
評(píng)論
圖片
表情

