你看过字符画吗?用 Python 自己实现一个吧

本文介绍如何使用Pillow库将图片转为灰度图,通过RGB灰度转换公式,结合字符映射,展示如何将彩色图片转化为黑白字符艺术作品。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

⛳️ 实战场景

如果你是一名程序员,你肯定在网上的代码中看到过下述注释,那有没有想过自己实现一个呢?
你看过字符画吗?用 Python 自己实现一个吧
先说原理:
图片由像素点构成,然后将每个像素点替换成一个字符,就可以将图片转换成字符画。

这是最简单的说明,但是每个像素点都有一种颜色,而且该颜色是由红绿蓝三色组成,红绿蓝即 RBG 值,如果将所有颜色与字符替换,那存在 256 x 256 x 256 = 1638400 中颜色,完全与字符替换是不可能的,此时就需要降低替换数量,这里就引入了灰度值,每个颜色值都可以转换成灰度值,而且灰度值的范围是 0-255,这样大幅降低了待替换数量,并且在 Python 中有现成的将图片转换为灰度图的库,实现起来就更加便捷了。

这里存在一个 RGB 转灰度值的公式:

gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
# 也可以使用下述公式,含义一致。
gray = (2126 * r + 7152 * g + 722 * b) / 10000

提前安装 pillow 库,用于将图片转换为灰度图。

⛳️ pillow 转灰度图

使用 pillow 库操作下述图片,将其转换为字符图:
你看过字符画吗?用 Python 自己实现一个吧
由于需要进行字符串替换,所以需要了解一些基本规则:

  • 颜色越浅,字符留白越多,当颜色为白时,使用空格字符;
  • 颜色越深,使用的字符笔画越多,例如黑色,可以使用 @ 这样的符号;

接下来我们就把图片转换成灰度值:

def img_to_char(path):
    img = Image.open(path)
    # 原图的宽和高
    ow, oh = img.size
    print(ow, oh)
    img = img.convert('L')
    img.show()


s = img_to_char('1.png')
print(s)

此时运行代码,就会得到一张灰色图片,效果如下:
你看过字符画吗?用 Python 自己实现一个吧
接下来将图片中每个像素点的灰度值都提取出来,做后一步计算。

from PIL import Image

def img_to_char(path):
    img = Image.open(path)
    # 原图的宽和高
    ow, oh = img.size
    print(ow, oh)
    img = img.convert('L')
    # img.show()
    char_img = ""
    for y in range(oh):
        s = ''
        for x in range(ow):
            # 取灰度值
            gray = img.getpixel((x, y))
            # char = gray_to_char(gray)
            s += str(gray)
        char_img = char_img + s + '\n'
    return char_img
s = img_to_char('1.png')
print(s)

此时会得到下图效果,一堆数字,在数字中还是可以发现部分差异的。
你看过字符画吗?用 Python 自己实现一个吧数字有了,接下来就是数字转换为字符了,你可以依据前文提及的【黑白】程度进行排列,例如下述内容:

@#$%&MNBEFRWYLIkbtj?*984532menocvzst{}[]1|()<>=+~-;:i^"'.

数量和内容都可以自行控制,最后放置一个空格,用来替换白色。

# 将灰度值转换成对应的字符
def gray_to_char(gray):
    all_char = """@#$%&MNBEFRWYLIkbtj?*984532menocvzst{}[]1|()<>=+~-;:i^"'. """
    char = all_char[int(len(all_char) * gray / 256)]
    return char

然后把前文数字拼接的位置,替换成该函数。

 char_img = ""
    for y in range(oh):
        s = ''
        for x in range(ow):
            # 取灰度值
            gray = img.getpixel((x, y))
            char = gray_to_char(gray)
            s += char
        char_img = char_img + s + '\n'
    return char_img

此时在运行代码,就可以得到一张超大的字符图,下图是表情包眼睛区域。
你看过字符画吗?用 Python 自己实现一个吧
接下来对图片进行一下优化,降低大小。

def img_to_char(path):
    img = Image.open(path)
    # 原图的宽和高
    ow, oh = img.size
    print(ow, oh)
    # 缩小高度和宽度
    w = int(ow * 0.3)
    h = int(oh * 0.3)
    # 调整图片大小
    img = img.resize((w, h))
    img = img.convert('L')
    # img.show()
    char_img = ""
    for y in range(h):
        s = ''
        for x in range(w):
            # 取灰度值
            gray = img.getpixel((x, y))
            char = gray_to_char(gray)
            s += char
        char_img = char_img + s + '\n'
    return char_img

等比例压缩之后,发现图片被拉伸了,原因是像素转换成文本,行与行之间有间隔,要缩小高度才能得到较好效果。
你看过字符画吗?用 Python 自己实现一个吧
高度缩小到原来的二分之一,代码如下所示:

# 缩小高度和宽度
w = int(ow * 0.3)
h = int(oh * 0.3)

h = h // 2
# 调整图片大小
img = img.resize((w, h))
img = img.convert('L')

此时就可以得到一个比较合理大小的图片了,是不是一模一样!
你看过字符画吗?用 Python 自己实现一个吧

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 711 篇原创博客

从订购之日起,案例 5 年内保证更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想橡皮擦

如有帮助,来瓶可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值