用Golang將圖片轉化成ASCII碼
用Golang將圖片轉化成ASCII碼
在開始之前先看看最終效果:
專案地址在這裡:ofollow,noindex" target="_blank">https://github.com/qeesung/im... , 歡迎star
我們都知道圖片是通過一個畫素點矩陣組成的,每一個畫素點都是有四個值,分別是R,G,B,A組成,其中RGB就是紅色,綠區,藍色,簡稱三原色,在計算機中取值從0-255,而A則是顏色的透明度,取值0.0-1.0。
我們現在要做的就是將一個彩色的圖片轉化成一個由ASCII組成的圖片,換句話說,就是將RGBA畫素點的矩陣轉化成一個由字元組成的矩陣,必要的時候再給字元加上顏色就可以啦。
(R, G, B, A) (R, G, B, A) (R, G, B, A)char1, char2, char3 (R, G, B, A) (R, G, B, A) (R, G, B, A)-->char4, char5, char6 (R, G, B, A) (R, G, B, A) (R, G, B, A)char7, char8, char9
那麼問題又來了,R,G,B的值都是從0-255的,而字元的數量是很有限的(一般我們只會用少數幾個有限的字元來表示),那麼我們如何將由多種組合的R,G,B對映到一個字元上呢?
convert(pixel) -> character
我們不妨將RGB值和透明度和在一起,算出一個總值權重W,然後將這個值W均分到不同的字串上,這樣就完成了畫素點到字元的對映,就是這麼簡單。注意下面的可選字串的從左往右" .,:;i1tfLCG08@"辨識度一次增加,或者辨識度依次減少,如果不這樣做,那麼圖片識別出來效果可能不太行。
value := (r + g + b) * a / 255 // Choose the char options.Pixels = " .,:;i1tfLCG08@" precision := float64(255 * 3 / (len(options.Pixels) - 1)) rawChar := options.Pixels[roundValue(float64(value)/precision)]
現在可以將畫素轉化為字元了,那麼顏色怎麼辦?上面的操作好比只是把圖片轉化成了黑白的,然後把輪廓畫出來來了,那麼如何取顏色呢?
加顏色需要注意的是,現在的顏色不再是單單的顏色了,現在的顏色包含兩塊,一塊是字元自身的顏色,即前景色,一塊是字元的後面的顏色,即背景色。
我們這裡不調整背景色,只渲染字元的前景色,即只渲染字元的顏色。
在linux終端中,是可以通過輸出特殊字元來配置輸出字元顏色的,拿著就好辦了,只需用圖片的RGB混合一下,輸出顏色就可以了,我們這裡用http://github.com/aybabtme/rg... 。
func decorateWithColor(r, g, b uint64, rawChar byte) string { coloredChar := rgbterm.FgString(string([]byte{rawChar}), uint8(r), uint8(g), uint8(b)) return coloredChar }
更多原始碼細節可以看這裡:https://github.com/qeesung/im... 歡迎star:clap: