Python3图片转字符画

通过Python3编写一个将图片转为字符画的程序。


github地址

一 环境

Python3 pillow-5.1

sudo pip3 install pillow

二 原理

  1. 字符画:

    字符画是一系列字符的组合,我们可以把字符看作是比较大块的像素,一个字符能表现一种颜色(暂且这么理解吧),字符的种类越多,可以表现的颜色也越多,图片也会更有层次感。

  2. 灰度值:

    指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像。

    可以使用以下灰度值公式:

    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
  3. 字符列表:

    我们可以创建一个不重复的字符列表,灰度值小(暗)的用列表开头的符号,灰度值大(亮)的用列表末尾的符号。

三 实现

  1. 在命令行中输入

    vim ascii.py

    或者在Pycharm中新建项目。

  2. 导入必要的库,argparse库用来管理命令行参数输入

    from PIL import Image
    import argparse
  3. 可以使用以下字符集,共70个字符,字符的种类与数量可以根据字符画效果更改。

    ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
  4. RGB值转字符的函数:

    def get_char(r,g,b,alpha = 256):
       if alpha == 0:
           return ' '
       length = len(ascii_char)
       gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
    
       unit = (256.0 + 1)/length
       return ascii_char[int(gray/unit)]
  5. ascii.py 完整代码:

    from PIL import Image
    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
    
    ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    
    
    # 将256灰度映射到70个字符上
    
    def get_char(r,g,b,alpha = 256):
       if alpha == 0:
           return ' '
       length = len(ascii_char)
       gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
    
       unit = (256.0 + 1)/length
       return ascii_char[int(gray/unit)]
    
    if __name__ == '__main__':
    
       im = Image.open(IMG)
       im = im.resize((WIDTH,HEIGHT), Image.NEAREST)
    
       txt = ""
    
       for i in range(HEIGHT):
           for j in range(WIDTH):
               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)

四 测试

  1. 下载测试用图片:

    wget http://labfile.oss.aliyuncs.com/courses/370/ascii_dora.png

    图片:

    input

  2. 运行程序:

    python3 ascii.py ascii_dora.png
  3. 查看结果:

    使用vim打开output.txt文件查看效果

    vim output.txt

    效果如图:

    output

猜你喜欢

转载自blog.csdn.net/TalonZhang/article/details/82432740