char添加一个字符_给你五十行代码把图片变成字符画!程序:太多了,一半都用不完...
今天和大家分享一個(gè)簡(jiǎn)單又好玩的Python項(xiàng)目–“圖片轉(zhuǎn)字符畫”。廢話不多說(shuō),先上一個(gè)效果圖迷惑一下眾生。
沒錯(cuò)的,圖片轉(zhuǎn)字符畫就是將我們平常所看到的的圖片根據(jù)像素RGB值和灰度值傳化成一個(gè)個(gè)字符串的過程。
嗯…聽起來(lái)有些費(fèi)腦子喔。沒關(guān)系,且聽小五為小伙伴一一分解。
像素RGB值
什么是像素RGB值?
其實(shí)就像我們平常所看到的所有圖片,無(wú)論是彩色照還是黑白照,其實(shí)它們都是有色彩的,更加神奇的是,我們?nèi)庋鬯吹降乃猩蕩缀醵际怯杉t(Red)、綠(Green)、藍(lán)(Blue)經(jīng)過不同深度的調(diào)色后得到的。
而RGB色彩模式就是是工業(yè)界的一種顏色標(biāo)準(zhǔn),是通過對(duì)紅?、綠(G)、藍(lán)(B)三個(gè)顏色通道的變化以及它們相互之間的疊加來(lái)得到各式各樣的顏色的。
所以RGB即是代表紅、綠、藍(lán)三個(gè)通道的顏色,這個(gè)標(biāo)準(zhǔn)幾乎包括了人類視力所能感知的所有顏色,是目前運(yùn)用最廣的顏色系統(tǒng)之一。
所以也可以說(shuō),我們所看到的所有具有色彩的圖片都是由這三種顏色調(diào)出來(lái)的。
而對(duì)于字符畫,顧名思義是一系列字符的組合,我們可以把字符看作是比較大塊的像素,一個(gè)字符能表現(xiàn)一種顏色。
就像我們剛才所看到的那張圖片轉(zhuǎn)成字符畫之后,畫中包含著各種不同層次的字符,所以字符的種類越多,可以表現(xiàn)的顏色也越多,圖片也會(huì)更有層次感。
那么小伙伴們可能就會(huì)問了,我們是要轉(zhuǎn)換一張彩色的圖片,這么多的顏色,要怎么對(duì)應(yīng)到只有一種顏色而且還包括那么多字符的的字符畫上去?
哈哈,不知道了吧?這里就要介紹灰度值的概念了。來(lái)來(lái)來(lái),科普一下!
灰度值計(jì)算
灰度值:指黑白圖像中點(diǎn)的顏色深度,范圍一般從0到255,白色為255,黑色為0,故黑白圖片也稱灰度圖像。
所以我們可以使用灰度值公式將像素的 RGB 值映射到灰度值,也就是下面這個(gè)公式:(注意這個(gè)公式是簡(jiǎn)化過的,真正的計(jì)算公式會(huì)復(fù)雜些)
灰度值計(jì)算公式gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
這樣就好辦了,我們可以創(chuàng)建一個(gè)不重復(fù)的字符列表,然后用每一個(gè)字符表示一種顏色,灰度值小(暗)的用列表開頭的符號(hào)表示,灰度值大(亮)的用列表末尾的符號(hào)表示。
注意!重點(diǎn)來(lái)了!敲黑板!!!
我們知道。單從黑色到白色,顏色深度的范圍就是0-255,也就是說(shuō)這一共有256個(gè)不同深淺的顏色,那我們?nèi)绻胍獙⒚恳环N顏色以不同的字符表示出來(lái),那豈不是需要256個(gè)不同的字符嘛?
哈哈,我覺得也是,去找256個(gè)不同的字符寫的你的程序里面組成一個(gè)字符串,想想都刺激,但是你會(huì)去這么做嘛?我想不會(huì)吧?
所以我們只需要想一種辦法,讓顏色深度相近的灰度值用不同的符號(hào)表示即可,所以我們可以定義一個(gè)存放不同字符的字符串,用來(lái)表示不同的色彩的字符。在這里定義的這個(gè)字符串的長(zhǎng)度是70。
定義代表灰度的字符ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ") #設(shè)置顯示的字符集
灰度值映射字符函數(shù)
之后我們只需要定義一個(gè)函數(shù),將我們需要轉(zhuǎn)化成字符畫的圖片的每一個(gè)像素找到與其相對(duì)應(yīng)的字符并返回即可。
該函數(shù)如下,傳入的參數(shù)是圖片上某一點(diǎn)處的像素值,同時(shí)還有一個(gè)透明度參數(shù):
將256灰度映射到70個(gè)字符上def get_char(r,g,b,alpha = 256):
#alpha為透明度
# 判斷 alpha 值,為0表示全透明
if alpha == 0:
return ' '
# 獲取字符集的長(zhǎng)度,這里為 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)行如下處理才能將灰度值映射到指定的字符上
#防止當(dāng)灰度值為255時(shí),輸出的第70個(gè)字符超出列表索引,所以需要將(255+1)
unit = (255.0 + 1)/length
# 返回灰度值對(duì)應(yīng)的字符
return ascii_char[int(gray/unit)]
當(dāng)我們寫好像素映射字符串的函數(shù)方法之后,我們就可以對(duì)不同的像素獲取到不同的字符表示了。
圖片導(dǎo)入及尺寸設(shè)置
那么接下來(lái)就是我們應(yīng)該如何獲取圖片上某一點(diǎn)處的像素了。這個(gè)時(shí)候我們需要調(diào)用pillow庫(kù),這個(gè)庫(kù)的作用就是對(duì)圖片進(jìn)行基本的處理。
在這里我們需要使用的是pillow庫(kù)下的Image類,使用Image下的resize方法,我們可以對(duì)圖片進(jìn)行縮放,并設(shè)置輸出的圖片質(zhì)量。
以下面這張圖片為例:
進(jìn)行圖片縮放和輸出質(zhì)量設(shè)置
IMG = 't01b2a945701805d7f1.jpg' #設(shè)置圖片文件WIDTH = 150 #設(shè)置字符畫的寬
HEIGHT = 80 #設(shè)置字符畫的高
im = Image.open(IMG)
im = im.resize((WIDTH,HEIGHT), Image.NEAREST)
遍歷圖片獲取字符
之后可以調(diào)用Image.getpixel()方法,給其傳入坐標(biāo)參數(shù)就可以返回該坐標(biāo)處的像素值,值得注意的地方是,如果這個(gè)坐標(biāo)處的像素是具有透明屬性的。
那么還會(huì)返回alpha透明度參數(shù),這就是為什么我們?cè)谟成渥址瘮?shù)方法的參數(shù)中傳入透明度參數(shù)并進(jìn)行判斷的原因。
將 (j,i) 坐標(biāo)的 RGB 像素轉(zhuǎn)為字符后添加到 txt 字符串txt += get_char(*im.getpixel((j,i)))
現(xiàn)在我們要做的就是對(duì)該尺寸的圖片進(jìn)行橫向和縱向的坐標(biāo)遍歷,獲取到每一個(gè)坐標(biāo)點(diǎn)處映射的字符,并將其在存儲(chǔ)在我們?cè)O(shè)定的存放圖片字符串的列表中即可。
遍歷圖片中的每一行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'
字符畫輸出和導(dǎo)入文件
最后將該字符列表在屏幕輸出或者存放到文本文件中,為了可以更好的看到字符畫的效果,在這里大灰狼建議將該字符列表存放到一個(gè)文本文件中。
導(dǎo)入文件OUTPUT = 'output5.txt' #設(shè)置存放字符畫的文本文件
#保存到文本文件
with open(OUTPUT,'w') as f:
f.write(txt)
將圖片轉(zhuǎn)字符畫處理后保存在文本文件中,我們可以在文本文件中找到被字符化后的照片了。
好了,到這里圖片轉(zhuǎn)字符畫的過程就基本結(jié)束了。
除去注釋最后不到25行,使用的小伙伴只需要將程序最上面的圖片路徑修改成自己的圖片即可!
總結(jié)
以上是生活随笔為你收集整理的char添加一个字符_给你五十行代码把图片变成字符画!程序:太多了,一半都用不完...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bootstrap 开源框架demo_5
- 下一篇: ideaspringboot项目上传服务