【003】Python实现图片转字符画(pillow 库的使用)

在常见的RGB(A)模式图片中,利用每个像素点的R,G,B值按照公式转换成灰度值(0~255),然后在自己创建的字符表中找到灰度值对应的字符,添加到一个文本文件中,就实现了图片转字符画(黑白)。

但是此方法不适用于颜色种类丰富的图片,虽然有对应256个灰度值正好存在256个字符,可以完全区分不同的灰度值,但是毕竟一个像素和一个字符 大小相差悬殊,转换后价值不大。

如果要转换一张宽高像素比较大的图片,除了使用ps等修图工具将像素改小,还可以使用pillow库改变图片大小。

这是我利用pillow库函数把图片像素改小后的转换:

其实这是一碗泡面~

因为改小了,图片上的字就失真了,看不清楚

直接贴代码了

/picTostr.py

#!/usr/bin/python
#-*- coding:utf-8 -*-
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)
# 获取参数数据,使用parse_args()解析 解析对象
args = parser.parse_args()

其中o,width,height为非必须参数,参数数据类型默认为字符串,除非设置type属性,default为参数默认数据。

不加’-‘表示必须参数,同时也是参数名称,此时名称不可以通过添加’- -‘修改;

加’-‘表示可选参数,此时参数名称为当前,如果后面有加’- -‘的,则参数名称改为’- -‘紧接的字符串,此时’-o’和’–output’均可作为输入时的参数声明;

必须参数必须按照add_argument()的顺序添加参数值(中间可插入非必须参数),非必须参数可以打乱顺序,但需要参数名称和参数值一一对应

以上eg:python picTostr.py –output picTostr_output.txt -height 50 test.jpg -width 100(打乱顺序)

class character():
    def __init__(self):
    self.IMG = args.file
    self.WIDTH = args.width
    self.HEIGHT = args.height
    self.OUTPUT = args.output
    # 不同字符代表不同色块,字符最好不要重复
    self.ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    self.txt = ''

    # 将256灰度映射到70个字符上
    # 图片格式为RGB的*im.getpixel((j,i)后会得到三个参数r(red),g(green),b(blue);RGBA得到四个参数r,g,b,alpha(透明度,0表示完全透明)
    # im.getpixel((j,i))得到一个由r, g, b, alpha(如果有的话)构成的元祖,加上*号即表示拆分元祖分别赋值引用
    def get_char(self, r, g, b, alpha = 256):
        # 如果是透明的,则输出空格
        if alpha == 0:
                return ' '
        length = len(self.ascii_char)
        # r,g,b转换为灰度值,白色是255,黑色是0
        gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
        # 单元字符的灰度值大小
        unit = (256.0 + 1)/length
        # 字符从小到大表示灰度值,已知灰度值大小,一个字符表示的灰度值大小,求该灰度值由第几个字符表示,ascii_char[i]
        return self.ascii_char[int(gray/unit)]

    def convert(self):
    im = Image.open(self.IMG)
    # im.resize(size,filter)
        # 变量filter为NEAREST、BILINEAR、BICUBIC或者ANTIALIAS之一
        # 如果忽略,或者图像模式为“1”或者“P”,该变量设置为NEAREST,速度快
        # ANTIALIAS 抗锯齿,质量最高;BICUBIC 三次样条插;BILINEAR 线性插值法
        im = im.resize((self.WIDTH,self.HEIGHT), Image.NEAREST)
        for i in range(self.HEIGHT):
            for j in range(self.WIDTH):
                self.txt += self.get_char(*im.getpixel((j,i)))
            self.txt += '\n'
    def save(self):
        if self.OUTPUT:
            with open(self.OUTPUT,'w') as f:
                f.write(self.txt)
        else:
            with open("output.txt",'w') as f:
                f.write(self.txt)
    def start(self):
    self.convert();
    self.save();

if __name__ == '__main__':
    c = character()
    c.start()

以前一直以为一些贴吧大神的小尾巴上字符画是手打出来了,看来是我太天真了。

关于pillow的使用,推荐看看这位大神的博客:

Python图像处理库PIL的基本概念介绍
Python图像处理库PIL的基本模块介绍
Python图像处理库PIL的Image模块介绍(一)
Python图像处理库PIL的Image模块介绍(二)
…………

讲的非常全,学完可以不用PS修图啦~

你可能感兴趣的:(pillow库)