c++ 保存透明gif_Python-字符版gif图

准备环境

对图片的操作我们可以使用PIL、imageio和image2gif库,处理像素我们选择使用opencv-python这个库。NumPy是Python语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。因此我们需要安装以下几个包:PIL、imageio、numpy、cv2、images2gif

pip install pillow
pip install imageio
pip install numpy
pip install opencv-python
pip install images2gif

以上扩展包安装时应该都可以顺利安装,但使用的时候有几个坑

1、导入cv2时,如果发生找不到dll的情况,大多数的原因都是当前的python版本和opencv版本不匹配,pip安装时默认选择了最新的版本,因此我们安装时需要指定安装的版本pip install opencv-python==3.4.1.15

2、使用images2gif这个库时,可能会出现无法导入writeGif接口的情况这个时候需要改下源码,把images2gif.py文件中的两个from 后边加上英文点号,修改如下

from .images2gif import readGif as readGif
from .images2gif import writeGif as writeGif

字符版动态图

首先我们需要搞清楚gif是个什么玩意儿,其实gif是将多幅图像保存为一个图像文件,从而形成动画,最常见的就是通过一帧帧的动画串联起来的搞笑gif图,所以归根到底gif仍然是图片文件格式。

什么?原来gif就是一帧一帧的图片,那么字符版动态图其实也就是字符版图片的连续播放,思考到这儿,我们有了如下思路:

1、拿到一张gif图

2、把fig图拆分成多张png图片,或者其他格式的图片

3、循环遍历拆分后的图片,并处理成字符版图片

4、把处理后的字符版图片在连接成一个guf文件

5、保存gif文件

通过以上5个步骤,我们即可实现我们的需求,是不是很简单,下边我们分布来讲解实现过程

四、gif和png转换

1、要想获得静态图片,我们需要有一个gif图,然后把gif图拆分成多张png图片,以下是3中处理gif图片的方式

方式1,使用Image

def 

方式2,使用Image

def Gif2Png_2():
    try:
        im = Image.open(gifpath)
    except IOError:
        print ("Cant load", gifpath)
        sys.exit(1)
    i = 0
    mypalette = im.getpalette()

    try:
        while 1:
            im.putpalette(mypalette)
            frame = im.convert('RGBA')
            new_im = Image.new("RGBA", im.size)
            #new_im.paste(im)
            new_im.paste(frame)
            new_im.save(saveFloder + "%d.png" % i)

            i += 1
            im.seek(im.tell() + 1)

    except EOFError:
        pass # end of sequence

方式3

#使用imageio处理gif图
def Gif2Png_3():
    images = imageio.mimread(gifpath)
    #把上面的每帧图片进行保存
    for i, img in enumerate(images):
        img = np.asarray(img)
        imageio.imwrite(saveFloder + "%d.png" % i, img)

生成png效果如下图所示

22369464b3c069a9b0362b1cf6326352.png

2、把图片处理成gif图,以下是处理的两种方式

方式1

def Png2Gif():
    fileOrder = sorted([int(os.path.splitext(x)[0]) for x in os.listdir(savePath)])
    frames = []
    for order in fileOrder:
        filename = str(order)+ '.png'
        filePath = savePath + "/" + filename
        frames.append(imageio.imread(filePath))
    
    imageio.mimsave(newFilePath, frames, 'GIF', duration = 0.1)

方式2

def Png2Gif_2():
    fileOrder = sorted([int(os.path.splitext(x)[0]) for x in os.listdir(savePath)])
    filenames = []         # 存储所需要读取的图片名称
    for order in fileOrder:
        filename = str(order)+ '.png'
        filePath = savePath + "/" + filename
        filenames.append(filePath)              # 将使用的读取图片汇总
        
    frames = []
    for image_name in filenames:                # 索引各自目录
        im = Image.open(image_name)             # 将图片打开,本文图片读取的结果是RGBA格式,如果直接读取的RGB则不需要下面那一步
        im = im.convert("RGB")                  # 通过convert将RGBA格式转化为RGB格式,以便后续处理 
        im = np.array(im)                       # im还不是数组格式,通过此方法将im转化为数组
        frames.append(im)                       # 批量化
    writeGif(newFilePath, frames, duration=0.1, subRectangles=False) # 生成GIF,其中durantion是延迟,这里是1ms

五、处理动态图片

生成字符版gif图时,如果把拆分开来的图片先进行保存硬盘,然后在进行图片处理在合成最终gif效率会比较慢,因此我们把整个过程都放在内容中处理,即拆分开来的png图片不进行存盘,而是直接处理,然后在合成gif图

def Gif2Gif(gifpath):
    A = []
    images = imageio.mimread(gifpath)
    #把上面的每帧图片进行保存
    for img in images:
        u, v, channels = 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, a = img[i, j]
                zifu = string[int(((len(string) - 1) * pix) / 256)]
                if a != 0:
                    cv2.putText(c, zifu, (j, i), cv2.FONT_HERSHEY_COMPLEX, 0.3, (int(b), int(g), int(r), int(a)))
                
        A.append(c)

    oldFileName = os.path.splitext(os.path.basename(gifpath))[0]
    newFilePath = os.getcwd() + '/{}/'.format(saveFloder) + oldFileName +"_new.gif"
    imageio.mimsave(newFilePath, A, 'GIF', duration=0.1)

源代码中是支持批量生成字符版gif图,测试生成效果如下图所示,左侧是原始图,右侧是生成的效果图

f9476dde8da7e409e852fae114839ebd.png

a7955c7aa9079a3c5e50566a0ba59385.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值