基于灰度图的字符画的制作

媒体上经常会出现一些字符表示的图片,这段ASCII字符是用来形容每个像素点的颜色深浅,从视觉效果(灰度)来看,字符的越复杂越能形容深色,我们只需要获得一张图并将这张图转化为灰度图,然后遍历其中的像素点的灰度值,并根据灰度值转化为相应的ASCII字符,最后存入一个txt文件中即可。

代码如下:

# -*- coding: utf-8 -*-
from PIL import Image

codeLib = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'. '''#生成字符画所需的字符集
count = len(codeLib)

def transform1(image_file):
    image_file = image_file.convert("L")#转换为黑白图片,参数"L"表示黑白模式
    codePic = ''
    for h in range(0,image_file.size[1]):  #size属性表示图片的分辨率,'0'为横向大小,'1'为纵向
        for w in range(0,image_file.size[0]):
            gray = image_file.getpixel((w,h)) #返回指定位置的像素,如果所打开的图像是多层次的图片,那这个方法就返回一个元组
            codePic = codePic + codeLib[int(((count-1)*gray)/256)]#建立灰度与字符集的映射
        codePic = codePic+'\r\n'
    return codePic

def transform2(image_file):
    codePic = ''
    for h in range(0,image_file.size[1]):
        for w in range(0,image_file.size[0]):
            g,r,b = image_file.getpixel((w,h))
            gray = int(r* 0.299+g* 0.587+b* 0.114)
            codePic = codePic + codeLib[int(((count-1)*gray)/256)]
        codePic = codePic+'\r\n'
    return codePic


fp = open(u'./2.jpeg','rb')
image_file = Image.open(fp)
image_file=image_file.resize((int(image_file.size[0]*0.75), int(image_file.size[1]*0.5)))#调整图片大小
print (u'Info:',image_file.size[0],' ',image_file.size[1],' ',count)

tmp = open('tmp.txt','w')
tmp.write(transform1(image_file))
tmp.close()

OpenCV的作用是实现图像从彩色到灰度图的转换

我们喂给程序一张图片:

基于灰度图的字符画的制作_第1张图片

运行程序:

基于灰度图的字符画的制作_第2张图片

得到输出文件:

查看字符图形效果:

基于灰度图的字符画的制作_第3张图片

基于灰度图的字符画的制作_第4张图片

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

生成字符画的字符集的设计是有根据的,如果把这个字符串看成一个数组,则数组前面的字符,对应于较小的灰度值,对应颜色偏黑,绘制出来的区域颜色深一些,而后面的字符,对应颜色偏白,绘制出来的区域颜色浅一些。

codeLib = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'. '''

GIF动图转为字符动图:

# -*- coding: utf-8 -*-
import imageio
import cv2

origin_pic='./a.gif'
target_pic='./b.gif'
codeLib = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'. '''#生成字符画所需的字符集

pics=imageio.mimread(origin_pic) #读取动态图,把动态图转换为一帧一帧的图像

#应用上面定义好的图片灰度与字符的映射,把上面的每帧图片都转化为字符画,并保存在一个列表中
A=[]

for img in pics:
    u,v,_=img.shape
    c=img*0+255
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    for i in range(0,u,6):
        for j in range(0,v,6):
            pix=gray[i,j]
            b,g,r,_=img[i,j]
            zifu=codeLib[int(((len(codeLib)-1)*pix)/256)]
            cv2.putText(c,zifu,(j,i),cv2.FONT_HERSHEY_COMPLEX, 0.3, (int(b),int(g), int(r)), 1)
    A.append(c)

imageio.mimsave(target_pic, A, 'GIF',duration=0.1) #把A列表里的字符画组合起来,变成动态图
print('转化完成,请到你保存的路径下查看')

基于灰度图的字符画的制作_第5张图片

基于灰度图的字符画的制作_第6张图片

转化后的结果:

结束!

你可能感兴趣的