Python2.7 图片合成gif

1.使用images2gif.writeGif 过程中出现两个错误

typeError:must be string or buffer, not None 
only integer scalar arrays can be converted to a scalar index

可能是各个packages的版本不对,经过各种尝试没有真正解决这两个错误。接着在网上找到合成gif的源码
发现还是出现该错误

typeError:must be string or buffer, not None

2.一开始我参照image2gif.py的解决方案,把_writeGifToFile中的

    for im in images:  
        if not previous:  
            # 第一个图像  
            # 获取相关数据  
            palette = getheader(im)[1]  #取第一个图像的调色板   

替换为

    for im in images:  
        if not previous:  
            # 第一个图像  
            # 获取相关数据  
            palette = im.palette.getdata()[1]  #取第一个图像的调色板  

之后生成的gif是灰色的。
3.我想这个肯定和调色板数据的读取有关。于是我找到imges2gif的源码的作者对这类似代码片段的最新修改,把它迁移到这边的源码,就work了。修改如下

 for im in images:  
        if not previous:  
            # 第一个图像  
            # 获取相关数据  
            palette=getheader(im)[0][-1]

全部代码如下:(修改address 和输入输出名字即可使用)

#coding=utf-8 

import time  
import string  
from PIL import Image, ImageChops  
from PIL.GifImagePlugin import getheader, getdata  
import os  

def intToBin(i):  
    """ 把整型数转换为双字节 """  
    # 先分成两部分,高8位和低8位  
    i1 = i % 256  
    i2 = int( i/256)  
    # 合成小端对齐的字符串  
    return chr(i1) + chr(i2)  
def getheaderAnim(im):  
    """ 生成动画文件头 """  
    bb = "GIF89a"  
    bb += intToBin(im.size[0])  
    bb += intToBin(im.size[1])  
    bb += "\x87\x00\x00"  #使用全局颜色表  
    return bb  
def getAppExt(loops=0):  
    """ 应用扩展,默认为0,为0是表示动画是永不停止 
    """  
    bb = "\x21\xFF\x0B"  # application extension  
    bb += "NETSCAPE2.0"  
    bb += "\x03\x01"  
    if loops == 0:  
        loops = 2**16-1  
    bb += intToBin(loops)  
    bb += '\x00'  # end  
    return bb  


def getGraphicsControlExt(duration=0.1):  
    """ 设置动画时间间隔 """  
    bb = '\x21\xF9\x04'  
    bb += '\x08'  # no transparancy  
    bb += intToBin( int(duration*100) ) # in 100th of seconds  
    bb += '\x00'  # no transparant color  
    bb += '\x00'  # end  
    return bb  
def _writeGifToFile(fp, images, durations, loops):  
    """ 把一系列图像转换为字节并存入文件流中 
    """  
    # 初始化  
    frames = 0  
    previous = None  
    for im in images:  
        if not previous:  
            # 第一个图像  
            # 获取相关数据  
            palette=getheader(im)[0][-1]
            #palette =im.palette.getdata()[1]  #取第一个图像的调色板  
            #print(type(palette))
            data = getdata(im)  
            imdes, data = data[0], data[1:]              
            header = getheaderAnim(im)  
            appext = getAppExt(loops)  
            graphext = getGraphicsControlExt(durations[0])  

            # 写入全局头  
            fp.write(header)  
            fp.write(palette)  
            fp.write(appext)  

            # 写入图像  
            fp.write(graphext)  
            fp.write(imdes)  
            for d in data:  
                fp.write(d)  

        else:  
            # 获取相关数据            
            data = getdata(im)   
            imdes, data = data[0], data[1:]         
            graphext = getGraphicsControlExt(durations[frames])  

            # 写入图像  
            fp.write(graphext)  
            fp.write(imdes)  
            for d in data:  
                fp.write(d)     
        # 准备下一个回合  
        previous = im.copy()          
        frames = frames + 1  

    fp.write(";")  # 写入完成  
    return frames    

def writeGif(filename, images, duration=0.1, loops=0, dither=1):  
    """ writeGif(filename, images, duration=0.1, loops=0, dither=1) 
    从输入的图像序列中创建GIF动画 
    images 是一个PIL Image [] 或者 Numpy Array 
    """  
    images2 = []  
    # 先把图像转换为PIL格式  
    for im in images:  

        if isinstance(im,Image.Image): #如果是PIL Image  
            images2.append( im.convert('P',dither=dither) )  

        elif np and isinstance(im, np.ndarray): #如果是Numpy格式  
            if im.dtype == np.uint8:  
                pass  
            elif im.dtype in [np.float32, np.float64]:  
                im = (im*255).astype(np.uint8)  
            else:  
                im = im.astype(np.uint8)  
            # 转换  
            if len(im.shape)==3 and im.shape[2]==3:  
                im = Image.fromarray(im,'RGB').convert('P',dither=dither)  
            elif len(im.shape)==2:  
                im = Image.fromarray(im,'L').convert('P',dither=dither)  
            else:  
                raise ValueError("图像格式不正确")

            images2.append(im)  

        else:  
            raise ValueError("未知图像格式")  

    # 检查动画播放时间  
    durations = [duration for im in images2]  
    # 打开文件  
    fp = open(filename, 'wb')  
    # 写入GIF  
    try:  
        n = _writeGifToFile(fp, images2, durations, loops)  
    finally:  
        fp.close()  
    return n  

############################################################  
## 将多帧位图合成为一幅gif图像  
def images2gif( images, giffile, durations=0.05, loops = 0):  
    seq = []  
    for i in range(len(images)):  
        im = Image.open(images[i])  
        background = Image.new('RGB', im.size, (255,255,255))  
        background.paste(im, (0,0))
        seq.append(background)  
    frames = writeGif( giffile, seq, durations, loops)  
    print frames, 'images has been merged to', giffile  


##############################################################   
    #frames = gif2images('source.gif',distDir='tmp',type='png')  
address='/home/lab-huang.junhong/DeepLearning/\
WGAN_experiment/gif_test_1'#experiment_CelebA_WGAN_s64_n27_b64_w5/
li=os.listdir(address)
li.sort() 
#name="1.jpg"#"fake_samples_1000.png"
images = []    
for name in li :
    if os.path.splitext(name)[1]==".png":
        images.append("{0}/{1}".format(address,name))  

gif_name="face.gif"
images2gif(images,"{0}/{1}".format(address,gif_name), durations = 0.5)

你可能感兴趣的:(python)