在这篇文章里头, 我们会去用到下面这些个知识点的哦。
完整的一个程序, 那个用来把图片转换成字符画的py脚本。
请先在命令行工具中找到存放图片文件的那个目录位置, 接着把当前路径切换到那个地方去执行操作, 然后启动名为图片转字符画.py的这个程序脚本并在其后面跟上参数.png这个后缀的标记。
这就拿来作为一个给图片用的名称呗。
from PIL import Imageimport 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)
args = parser.parse_args()
IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft"
"/\|()1{}[]?
-_+~<>i!
lI;:,\"^`'. ")
def get_char(r, g, b, alpha=256):
# 判断 alpha 的值
if alpha == 0:
return ' '
# 获取字符集的长度
length = len(ascii_char)
# 将 RGB 值转为灰度值 gray,灰度值范围为 0-255
gray = int(0.2126*r + 0.7125*g + 0.0722*b)
unit = (255.0 + 1)/length
return ascii_char[int(gray/unit)]
if __name__ == '__main__':
# 打开并调整图片的宽和高
im = Image.open(IMG)
# WIDTH, HEIGHT = im.size
# 调整图片尺寸对应到输出的字符画的宽度和高度, Image.NEAREST 表示输出低质量的图片
im = im.resize((WIDTH, HEIGHT), Image.NEAREST)
# 初始化输出的字符串
txt = ""
# 遍历图片中的每一行
for i in range(HEIGHT):
# 遍历该行中的每一列
for j in range(WIDTH):
# 将(j,i)坐标的 RGB 像素转为字符后添加到 txt 字符串
txt += get_char(*im.getpixel((j, i)))
# 遍历完一行后需要增加换行符
txt += '\n'
# 输出到屏幕
print(txt)
# 字符画输出到文件
if OUTPUT:
with open(OUTPUT, 'w') as f:
f.write(txt)
else:
with open('output.txt','w') as f:
f.write(txt)
主要的思路, 是首先通过模块去获取图片当中的RGB属性。接着, 要把这些RGB数值转换成灰度值。然后, 根据得到的数值来匹配合对的字符进行拼接。最后, 再把处理好的内容输出到文件里面。接下来是对这个使用的库做简要介绍。
将图片进行展示。
im = Image.open(IMG)im.show()
图片基本属性
print(im.size,im.format,im.mode)# (100,100),PNG,RGB
调整图片大小
im.resize((w, h), Image.NEAREST)获取该像素点的红色、绿色与蓝色的数值, 最终返回的结果是一个包含这三种元素值的元组格式。
im.getpixel((i,j))进行获取字符画的相关操作。
灰度值与RGB简介
灰度值说的是黑白图像里那个点的颜色深度情况, 它的数值范围一般是从零零到二五五这样来的, 当数值是一百五十五的时候代表白色, 是零的时候代表黑色, 所以我们就把那种黑白图片也叫作灰度图像了。
RGB色彩模式是工业界使用的一种颜色标准, 它是通过对红, 简称r的颜色通道进行操作, 还有绿, 简称g的颜色通道, 以及蓝, 简称b的颜色通道的变化来处理颜色的, 这些变化包括通道自身的变化, 也包括它们相互之间的叠加, 通过这种方式来得到各式各样的颜色, rgb这三个字母即是代表红绿色的三个通道中的红色, 绿色, 蓝色这三个通道的意思, 这个标准几乎包括了人类视力所能感知的所有颜色, 所以它就是目前运用最广的颜色系统之一。
把像素的红、绿、蓝这三个通道的数值放一起, 套进灰度值的那个计算公式里面去算, 最后就能得到这个像素对应的灰度值了。
gray = 0.0216*r + 0.7125*g + 0.0722*b接着, 你可以去创建出一个里面的元素不会互相重复的字符组成的列表, 其中对于灰度值比较小也就是相对较暗的部分使用这个列表开头位置的符号来进行表示, 而对于灰度值比较大也就是相对较亮的部分则使用这个列表最末尾处的符号来进行表示。
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")最后一步是建立灰度数值和对应的字符画元素之间的映射关系。
gray = int(0.2126*r + 0.7125*g + 0.0722*b)unit = (255.0 + 1)/length
return ascii_char[int(gray/unit)]
文件保存
当.txt文件不存在的时候, 我们就去创建它, 而当该文件已经存在的时候, 我们就用新的内容将其覆盖掉。
# 字符画输出到文件if OUTPUT:
with open(OUTPUT, 'w') as f:
f.write(txt)
else:
with open('output.txt','w') as f:
f.write(txt)
库命令行输入
首先,利用那个带点的圆括号把实例给创建出来。然后, 再往里面加上命令行参数。大家需要注意, 在参数'--width'的前面有两个连字符。这两个连字符表示这是一个可选参数。所以, 当大家在命令行输入命令的时候, 可以选择这样去做。
python file.py imagename.pngpython file.py imagename.png --width=100
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)
# 解析并获取参数
args = parser.parse_args()
IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output