实质上,动的图本身是由静态图片组成的,所以可以拆分来看:
1.把动态图装换为静态图片 ImageSequence
2.对每一张静态图片来说:
(1)灰度化
(2)静态的图转化为一系列的字符
(3)颜色深的用#,颜色浅的用' . ',' 0 '等
(4)把字符做成画 ImageDraw
3.把多张静态的字符画变成动态的图
具体代码
from PIL import Image,ImageDraw,ImageSequence
#动图的存储路径
source = r'E:\Desktop\xiaohuangya.gif'
#读入图片
def gifToChar():
new_frames=[]
with Image.open(source) as im:
#把动图变成静图,并存放在frames中
frames=[f.copy() for f in ImageSequence.Iterator(im)]
#将frames中的每一张静态图存放在文件当中
for i,frame in enumerate(frames):
#frame.save('%d.png'%i)
res = imageToChar(frame)
#with open('%d.txt'%i,'w') as f:
# f.write(res)
#txtToImage(res).save('%d.png'%i)
#把多张字符图存储到list中
new_frames.append(txtToImage(res))
imageToGif(new_frames)
#图片转换成字符
def imageToChar(img):
#灰度化
img=img.convert('L')
#获取图片的宽和高
width = img.width
height = img.height
#将图片宽和高缩短一半并进行压缩
img=img.resize((int(height/2),int(width/2)),Image.NEAREST)
txt=''
#循环遍历每一个像素,先宽再高
for h in range(img.height):
for w in range(img.width):
#由像素值获取到一个字符,把字符连接到txt中
txt+=get_char(img.getpixel((w,h)))
txt+='\n'
return txt
#根据传来的像素值,返回一个字符
def get_char(pix):
#无实际意义,主要是前面的比较充实,后面的看起来比较小
char_list='@B%8&WM#*abunhkpqwmasdfghjklzzcvunxrjft/\|{}1()[]?I-_+~<>i!1:;,.\.'
#获取字符串长度
char_len=len(char_list)
#计算下标
index=int((pix/255)*(char_len-1))
return (char_list[index])
#多张静态图转换字符图
def txtToImage(txtstring):
#创建一个空的页面1200*1200大小的白色页面
img=Image.new('RGB',(1200,1200),(255,255,255))
draw=ImageDraw.Draw(img)
#写入文件的内容
draw.text((0,0),txtstring,fill='black')
return img
#多张字符画变动图
def imageToGif(frames):
frames[0].save('newDuck.gif',save_all=True,append_images=frames[1:])
gifToChar()
最终实现效果(局部)