zoukankan      html  css  js  c++  java
  • Python-字符版gif图

    一、背景

        上一篇文章我们讲了怎么做自己的炫酷二维码,需要的移驾Python-炫酷二维码,本片文章我们讲述下怎么把一张图片处理成字符版图片,就是说使用字符替代每个像素的颜色,形成一个由字符组成的图片,并且字符的颜色是由原始的图片像素颜色决定

    二、准备环境

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

    1 pip install pillow
    2 pip install imageio
    3 pip install numpy
    4 pip install opencv-python
    5 pip install images2gif

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

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

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

    1 from .images2gif import readGif as readGif
    2 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

    1 def Gif2Png():
    2     gif = Image.open(gifpath)
    3     try:
    4         while True:
    5             current = gif.tell()
    6             gif.save(saveFloder + "/%d.png" % current)
    7             gif.seek(current + 1)
    8     except:
    9         pass

    方式2,使用Image

     1 def Gif2Png_2():
     2     try:
     3         im = Image.open(gifpath)
     4     except IOError:
     5         print ("Cant load", gifpath)
     6         sys.exit(1)
     7     i = 0
     8     mypalette = im.getpalette()
     9 
    10     try:
    11         while 1:
    12             im.putpalette(mypalette)
    13             frame = im.convert('RGBA')
    14             new_im = Image.new("RGBA", im.size)
    15             #new_im.paste(im)
    16             new_im.paste(frame)
    17             new_im.save(saveFloder + "\%d.png" % i)
    18 
    19             i += 1
    20             im.seek(im.tell() + 1)
    21 
    22     except EOFError:
    23         pass # end of sequence

    方式3

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

       生成png效果如下图所示

     

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

    方式1

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

    方式2

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

    五、处理动态图片

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

     1 def Gif2Gif(gifpath):
     2     A = []
     3     images = imageio.mimread(gifpath)
     4     #把上面的每帧图片进行保存
     5     for img in images:
     6         u, v, channels = img.shape
     7         c = img * 0 + 255
     8         gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
     9         for i in range(0, u, 6):
    10             for j in range(0, v, 6):
    11                 pix = gray[i, j]
    12                 b, g, r, a = img[i, j]
    13                 zifu = string[int(((len(string) - 1) * pix) / 256)]
    14                 if a != 0:
    15                     cv2.putText(c, zifu, (j, i), cv2.FONT_HERSHEY_COMPLEX, 0.3, (int(b), int(g), int(r), int(a)))
    16                 
    17         A.append(c)
    18 
    19     oldFileName = os.path.splitext(os.path.basename(gifpath))[0]
    20     newFilePath = os.getcwd() + '/{}/'.format(saveFloder) + oldFileName +"_new.gif"
    21     imageio.mimsave(newFilePath, A, 'GIF', duration=0.1) 

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

    六、字符版动态二维码

    有了普通的gif图生成动态二维码的方式,字符版gif图也就顺理成章的可以。

    测试生成效果如下图所示,左侧是原始图,右侧是生成的效果图

    七、源码下载

      需要全部代码的到csdn直接下载:Python-字符版gif图

    转载声明:本站文章无特别说明,皆为原创,版权所有,转载请注明:朝十晚八

  • 相关阅读:
    分享上大学时CCTV5经常播放的一段宣传片
    嗯, 在Vista下面post一篇, 快过年的二三事
    [转自天涯]很多年以前,我是一个中锋
    关于Anthem的Button控件, 为啥仍然会PostBack?
    小白三下杭州
    搜狗, 谷歌, 紫光, 3大输入法互打结果.
    2008春节回家流水账
    早上拍的雪景.
    如果安装.net framework 3.5出错, 可以这样解决
    我那幸福的坐车偶记...
  • 原文地址:https://www.cnblogs.com/swarmbees/p/10008985.html
Copyright © 2011-2022 走看看