主要思路

读取彩色图片的RGB值,利用公式转化为灰度值,并建立灰度值与自定义字符集质检的映射关系。最后将每个像素对应的字符按照原位置打印出来

公式和库灰度值 = 0.2126 * r + 0.7152 * g + 0.0722 * b

这是一个比较有名的心理学公式,系数的取值依据的是人眼对不同原色的敏感度不同。Pillow(PIL)库

Python的一个图像处理库。使用前需要安装。

Linux python3 环境下安装: sudo pip3 install pillowargparse 库

命令行选项与参数控制库。系统库,使用前需import

测试图片和结果

偷偷表白居老师^_^

源代码

编译时如果因为中文编码报错,需要在代码第一行添加 #coding=utf-8 指定中文编码方式。

from PIL import Image
#安装图像处理库 pillow(PIL)
import argparse
#处理命令行参数的输入
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)
'''

第一个参数file为位置参数,多个位置参数必须按定义顺序赋值。

-,--表示参数为可选参数。-后面只能跟一个字母,--后面可跟任意字符串

可选参数可以不赋值,也可以插在位置参数的任意位置,无需按顺序赋值

Eg. Python3 ascii.py -height 75 ascii_dora.png 代表了将ascii_dora.png赋值给file变量,75 赋值给height。output和width缺省
'''
args = parser.parse_args()
IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output
ascii_char = list("@@@*o0'/\0o*`.`.")
#ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
'''

字符串列表里面的内容可以自己根据图片色块的不同自行定义。可能需要多次测试才能有比较好的结果。

一般来说,越前面的字符串,代表灰度值越低,越接近黑色

注释掉的70个字符(最后一个字符是空格)是比较常用的一个序列,供大家参考

'''
def get_char(r,g,b,alpha = 256):
if alpha == 0:
return ' '
'''

透明色要单独处理,因为(225,225,225)白色,(0,0,0)黑色。透明色(0,0,0,0),如果不单独处理,就会被当成黑色

'''
length = len(ascii_char)
gray = int(0.2126*r+0.7152*g +0.0722*b)

#业界惯用的彩色图像转灰度图像公式之一。

#浮点数的运算比较耗时间,所以写成 gray = 2126*r+7152*g +0722*b)/10000会快一点。

unit = (256.0+1)/length
#unit = (256.0)/length也可以。

#一定要写256.0,强行把整型转换为浮点型,否则两个整型相除默认为整型,则unit全部都会为0

if gray > 250:
return ' '

#强行把近似白色的部分,当成背景做透明化处理。要不要这样做需要根据图片来决定。

return ascii_char[int(gray/unit)]
if __name__=="__main__":
im = Image.open(IMG) #生成一个image类
im = im.resize((WIDTH,HEIGHT),Image.NEAREST)
'''

PIL.Image.NEAREST:最低质量, PIL.Image.BILINEAR:双线性,PIL.Image.BICUBIC:三次样条插值,Image.ANTIALIAS:最高质量

resize 可以用来缩小,也可以放大,不过放大的话,显然很容易马赛克

'''
txt = ""
for i in range(HEIGHT):
for j in range(WIDTH):
txt += get_char(*im.getpixel((j,i)))
'''

getpixel根据图片的不同,返回值也不同。灰度图像返回指定像素的灰度值,RGB图像返回

(R,G,B)元组,RGBA返回(R,G,B,Alpha),其中Alpha为透明度

*是元组传参数值给函数的一种用法,代表将元组解包,分别传给对应的变量。

'''
txt += '\n'
print (txt)
if OUTPUT:
with open(OUTPUT,'w') as f:

#with是与资源访问有关的异常处理功能。无论访问过程中是否出现异常,在with语句块结束后,都会自动关闭资源,解除占用

#以写的方式打开OUTPUT指定的文件,并将其赋予变量f

f.write(txt)
else:
with open("output.txt",'w') as f:
f.write(txt)