PIL:python的一个图形处理库
os:python的一个标准库,提供操作系统功能的一些函数
我们都知道图片都是由一个一个的像素点组成的(如下图所示),每个像素点又由三种颜色R红色、G绿色、B蓝色各自按0到255组合而成,颜色所代表的数字越大,这个颜色在这个像素点中越亮,反之越暗,比如白色的RGB值为(255,255,255),黑色的RGB值为(0,0,0)。RGB一共有256×256×256=16777216种组合!
如果我们将图片变为灰度图
看起来是不是像黑白图片,但是在灰度图中其实不止有纯黑纯白这两种颜色,灰度图的像素在黑色和白色中间还有许多过渡的颜色,分为256阶,0到255,数字越大越亮,越小越暗,因为灰度图的像素只用一个整数表示,所以一个像素就只有256种可能,那样对于图片转为字符画来说那将变得非常容易。
我们可以列出一串字符串表示灰度值从暗到亮的像素(最后一个字符为空格)
$#%@&MNBEFRWYLIkbtj?*984532menocvzst{}[]1|()<>=+~-;:i^"'.
这个没有固定数量与排序,不一定要非常多个,不过如果排列得当且数量多一些,最后呈现出来的字符画会更加精细一些。
看到这里原理已经非常地明显了,将每个像素点按灰度值的大小选择相对黑白像素密集程度的字符,并按原图片的像素顺序排序,这样字符画就可以出现啦!那么,我们开始动手吧!
首先第一步,我们要知道像素的灰度值,我们平时用到的图片基本上都是用RGB表示像素的,不知道灰度值怎么办呢?所以这里我们要引入一个公式:
Gray=R*0.299 + G*0.587 + B*0.114
这个公式可以让我们根据像素的RGB的值算出对应的灰度值,
比如纯黑色(0,0,0)的灰度值为0*0.299+0*587+0*0.114=0
,
纯白色(255,255,255)的灰度值为255*0.299+255*0.587+255*0.114=255
灰度值的问题解决了,接下来我们来解决一下如何将灰度值转换为对应复杂程度的字符
def g2s(gray):#设置参数输入像素的灰度值
pixel_str='''$#%@&MNBEFRWYLIkbtj?*984532menocvzst{}[]1|()<>=+~-;:i^"'. '''
length=len(pixel_str)
plus=255/length #字符之间的灰度区间
str_gray=0 #str_gray表示字符所代表的灰度值
for i in range(length):
str_gray = str_gray + plus
if gray <=str_gray:
return pixel_str[i]
我们来测试一下
>>>g2s(255)
' '
>>>g2s(0)
'$'
>>>g2s(250)
'.'
可以了!不过这里需要注意一点的是plus
的结果是浮点数,根据pixel_str
的长度计算出浮点数,若你写的长度跟我的不一样就可能会出现plus全部加完了还是比255小的情况,从而导致函数无法输出结果,这时可以将str_gray
的初始值设置为1就可以正常运行了。
下一步我们开始写主函数
from PIL import Image
import os
def img2str(img_path,save_path,num=0):
txt_path=os.path.join(save_path,'img.txt')
f=open(txt_path,'w')
f.write('')
f.close() #因为此目录有可能已有内容,所以先清空
f=open(txt_path,'a') #a表示在文件的末尾添加
im=Image.open(img_path)
if num==0:#因为有些图片尺寸过于大,所以添加了一个修改大小的功能
pass
else:
im=im.resize( ( int(im.size[0]/num),int(im.size[1]/num) ) )
im=im.convert('RGB')#因为有些图片不是RGB格式的,所以我们先要将其转换成RGB格式
for y in range(im.size[1]):
for x in range(im.size[0]):
r,g,b=im.getpixel((x,y))[0],im.getpixel((x,y))[1],im.getpixel((x,y))[2]
gray=r*0.299+g*0.587+b*0.114 #代入公式
s=g2s(gray) #我们在上面实现的函数
f.write(s)
f.write('\n') #每一行结束后换行
f.close()
当然,还有更简单的写法
im=im.convert('L')#直接将图片转换成灰度模式
for y in range(im.size[1]):
for x in range(im.size[0]):
s=g2s(im.getpixel((x,y)))
f.write(s)
f.write('\n')
f.close()
不过为了运用上面所学到知识,这里就用上面那一版。
准备一张图片test.jpg
在文档末尾添加以下代码,根据你的路径修改参数
if __name__=='__main__':
img2str(r'C:\\Users\\Felix\\Desktop\\test.jpg',r'C:\Users\Felix\Desktop',4)
运行程序,在桌面生成文件img.txt
,打开查看,成功!如果你的字符画看起来很混乱的话,请将自动换行关闭。
图片转字符画的讲解就到这里了,代表像素的字符串如果设置得合理的话,那么生成的字符画会更加地细致一些。你可以为这个程序打造一个gui界面,我之前就用过tkinter为这个程序写了一个简单的界面,你还可以用pyinstaller打包成exe文件,这样就可以和朋友们分享啦!