python 使用pillow库实现图片转字符画

原理说明

一张彩色图片是由一个个像素点组成的,字符画就是通过一些列的字符的组合,我们可以将字符看作是一个大块的像素,而那么多的颜色有怎么对应到字符呢,我们可以先将像素点的RGB值转化为灰度值,再将灰度值映射为字符。

灰度值:指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像。
RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

我们使用简易的sRGB IEC61966-2.1 公式,将像素的RGB值映射为灰度值:

sRGB IEC61966-2.1公式:
Gray = (R^2.2 * 0.2126  + G^2.2  * 0.7152  + B^2.2  * 0.0722)^(1/2.2)
我们这里就没有必要去各种指数运算,只需要将RGB转化成一个值就可以了
简易的换算公式:
gray = 0.2126 * r + 0.7152 * g + 0.0722 * b

然后我们定义一个补充的字符列表,将灰度值映射为列表中的字符。

完整代码

# -*- coding: utf-8 -*-

import argparse

from PIL import Image

parser = argparse.ArgumentParser()  # argparse 模块是Python标准库中推荐的命令行解析模块。使用说明可参考 https://docs.python.org/zh-cn/3/howto/argparse.html

parser.add_argument('file')  # 转换图片路径
parser.add_argument('-o', '--output', default="output.txt")  # 输出字符画文件路径,默认输出到当前路径下的output.txt

args = parser.parse_args()

IMG = args.file
OUTPUT = args.output

WIDTH = 40
HEIGHT = 40
ASCII_CHAR_LIST = list("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;,.*@-+#$%^ ")  # 字符列表


def get_ascii_char(r, g, b, alpha=256):
    if alpha == 0:
        return ' '
    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
    unit = (256.0 + 1) / len(ASCII_CHAR_LIST)
    return ASCII_CHAR_LIST[int(gray / unit)]


if __name__ == '__main__':
    im = Image.open(IMG)
    im = im.resize((WIDTH, HEIGHT), Image.NEAREST)

    output = ""

    for i in range(HEIGHT):
        for j in range(WIDTH):
            output += get_ascii_char(*im.getpixel((j, i)))  # 获取坐标处的RGB像素值
        output += '\n'
    print(output)

    with open(OUTPUT, 'w') as f:
        f.write(output)

效果展示

代码运行

代码运行

示例原图

转换生成的字符画

posted @ 2020-12-04 21:28  wwzhen  阅读(591)  评论(0)    收藏  举报