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


    ⛳️ 实战场景

    如果你是一名程序员,你肯定在网上的代码中看到过下述注释,那有没有想过自己实现一个呢?
    你看过字符画吗?用 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
    
    • 1
    • 2
    • 3

    提前安装 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    此时运行代码,就会得到一张灰色图片,效果如下:
    你看过字符画吗?用 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

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

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

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

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

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

     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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    此时在运行代码,就可以得到一张超大的字符图,下图是表情包眼睛区域。
    你看过字符画吗?用 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

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

    # 缩小高度和宽度
    w = int(ow * 0.3)
    h = int(oh * 0.3)
    
    h = h // 2
    # 调整图片大小
    img = img.resize((w, h))
    img = img.convert('L')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

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

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

  • 相关阅读:
    [剑指 Offer 24] 反转链表
    荐书丨《实验心理学指导手册》:如何快速掌握一篇文献中的实验范式
    某学院 期末test
    初识数据结构——时间复杂度
    React之Jsx如何转换成真实DOM
    传奇外网架设教程
    【JavaEE】MyBatis 单表查询易错问题(添加后返回自增id,${}与#{},SQL注入,模糊查询)
    试题 算法提高 最大连续子段和
    面经 | Go语言知识点
    【学习笔记73】设计模式
  • 原文地址:https://blog.csdn.net/hihell/article/details/126134477