在开始以前先看看最终效果:linux
项目地址在这里:https://github.com/qeesung/im... , 欢迎stargit
咱们都知道图片是经过一个像素点矩阵组成的,每个像素点都是有四个值,分别是R,G,B,A组成,其中RGB就是红色,绿区,蓝色,简称三原色,在计算机中取值从0-255,而A则是颜色的透明度,取值0.0-1.0。github
咱们如今要作的就是将一个彩色的图片转化成一个由ASCII组成的图片,换句话说,就是将RGBA像素点的矩阵转化成一个由字符组成的矩阵,必要的时候再给字符加上颜色就能够啦。bash
(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映射到一个字符上呢?ui
convert(pixel) -> character
咱们不妨将RGB值和透明度和在一块儿,算出一个总值权重W,而后将这个值W均分到不一样的字符串上,这样就完成了像素点到字符的映射,就是这么简单。注意下面的可选字符串的从左往右" .,:;i1tfLCG08@"辨识度一次增长,或者辨识度依次减小,若是不这样作,那么图片识别出来效果可能不太行。spa
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)]
如今能够将像素转化为字符了,那么颜色怎么办?上面的操做比如只是把图片转化成了黑白的,而后把轮廓画出来来了,那么如何取颜色呢?3d
加颜色须要注意的是,如今的颜色再也不是单单的颜色了,如今的颜色包含两块,一块是字符自身的颜色,即前景色,一块是字符的后面的颜色,即背景色。code
咱们这里不调整背景色,只渲染字符的前景色,即只渲染字符的颜色。blog
在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👏