您的位置:首页 > 编程语言 > Python开发

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

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

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

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

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



[align=center]其实这是一碗泡面~[/align]

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

直接贴代码了

/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修图啦~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: