Python实现图片换ASCII文本图像

图像在计算机中的表示

图像在计算机中的采用RGB加色模型显示的。在计算机内部,图像拥有4个属性

  • R: 红色
  • G: 绿色
  • B: 蓝色
  • A: 透明度(alpha)
  • RGB: 取值范围 0 − 255 0-255 0255,数值越大,颜色越深
  • A: 取值范围 0 − 255 0-255 0255,0表示完全透明,255表示完全不透明

任意一种颜色,在计算机中都可以用4个数字表示。

from PIL import ImageColor

# 查看各种颜色的RGBA值
print(ImageColor.getcolor('red', 'RGBA'))
# (255, 0, 0, 255)

# 黑色表示没有任何颜色,所以RGB值都是0
print(ImageColor.getcolor('BLACK', 'RGBA'))
# (0, 0, 0, 255)

print(ImageColor.getcolor('blue', 'RGBA'))
# (0, 0, 255, 255)

# 白色代表RGB全部的混合
print(ImageColor.getcolor('white', 'RGBA'))
# (255, 255, 255, 255)

不同的颜色,RGB三个数值之和肯定不同,因此就可以建立起RGB之和关于字符集合中每个字符的一一映射关系。但实际上,由于RGB之和最大为765,而输入的ASCII字符远远没有这么多。所以,需要对RGB之和进行同等比例缩小映射。

还有,对于RGB之和的数值,不能简单地将三者相加,需对RGB各个数值分配权重再相加。借助灰度值公式可以得到比较恰当的RGB转灰度值结果

0.2126 * r + 0.7152 * g + 0.0722 * b

可以计算每个像素点的灰度值之后,就需要对整个图像所有像素点进行处理。在计算机中,图像可以理解为一个二维数组(矩阵),数组每个值是对于某个像素点的RGB值。因此,只需要遍历计算数组中每个值就行了。

处理图像

Python中的提供了PIL模块来实现对图像的处理

from PIL import Image

load_image = Image.open('./test.png')
print(load_image.size)  #获取图像得到宽和高

获取图像二维数组中每个坐标的RGBA的值

width, height = load_image.size
image_RGBA = []
for row in range(height):
    row_RGBA = []
    for col in range(width):
        # getpixel((x, y))获取坐标的RGBA值
        row_RGBA.append(image.getpixel((row, col)))
    image_RGBA.append(row_RGBA.copy())
    row_RGBA.clear()
print(image_RGBA)
# [[(255, 255, 255, 0), (255, 255, 255, 0), (255, 255, 255),...

接下来计算图像的灰度值,并将其等比映射到ASCII字符集中

# 计算灰度值
gray_value = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
# 计算放缩比例
ratio = 256 / len(ascii_char)
# 返回索引所对应的ASCII
ascii = ascii_char[int(gray_value / ratio)]

输出ASCII字符图像

将灰度值映射到ASCII字符集的数值,视为ASCII字符集的索引值index。打印时,依次读取ascii_char[index]的再输出即可。

ascii_print = ""
for row in ascii_list:
    for col in row:
        ascii_print += ascii_char[col]
    ascii_print += '\n'
print(ascii_print)

重构代码

整个处理过程分三步走

  • 读取图像每个像素RGB值
  • 计算图像每个像素对应的灰度值,并得到映射字符集合的索引
  • 根据索引值获取字符,保存并输出

重构一下整个代码,并添加保存字符图像文本的功能。
完整代码

运行结果

对应稍微“复杂”的图像,转成ASCII文本显示效果并不好。因为每种颜色都会计算出一个灰度值,然后对应一个字符,这样会显得密密麻麻的。只有颜色单调,且图像轮廓清晰,有无太多背景色的图像,效果比较好。
花
哆啦A梦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值