点击上方“AI搞事情”关注我们
GIF(Graphics Interchange Format,图形交换格式)是一种位图图像格式。
GIF格式的图像文件具有如下特点:
GIF格式图像文件的扩展名是“.gif”。
对于灰度图像表现最佳。
具有GIF87a和GIF89a两个版本。
采用改进的LZW压缩算法处理图像数据。
调色板数据有通用调色板和局部调色板之分,有不同的颜色取值。
不支持24bit彩色模式,最多存储256色。
1. matplotlib
matplotlib 中的 animation 模块绘制动态图,绘制心形动态函数
安装matplotlib
pip install matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
# fig.patch.set_alpha(0.) # 设置透明背景,但animation不起作用
plt.axis('off') # 关闭坐标轴
#初始化窗口和坐标轴
xdata, ydata = [], []
#初始化x,y列表
ln, = ax.plot([], [], 'r-', animated=False)
#初始化绘制曲线的参数。
#init()函数初始化x,y轴范围
def init():
ax.set_xlim(-20,20)
ax.set_ylim(-20,15)
return ln,
#迭代器,根据传入的frame更新x,y值
def update(frame):
# 心形函数
x = 16 * np.sin(frame) ** 3
y = 13 * np.cos(frame) - 5 * np.cos(2 * frame) - 2 * np.cos(3 * frame) - np.cos(4 * frame)
xdata.append(x)
ydata.append(y)
ln.set_data(xdata, ydata)
return ln,
# interval:帧持续时间(milliseconds)
anim = animation.FuncAnimation(fig, update, frames=np.linspace(0, 10, 100), init_func=init, interval=1, repeat=False, blit=True)
anim.save('tmp.gif', writer='pillow')
plt.show()
动态图无法绘制透明背景。
2. imageio
pip install imageio
https://blog.csdn.net/guduruyu/article/details/77540445
# -*- coding: UTF-8 -*-
import imageio
def create_gif(image_list, gif_name):
frames = []
for image_name in image_list:
frames.append(imageio.imread(image_name))
# Save them as frames into a gif
imageio.mimsave(gif_name, frames, 'GIF', duration=0.01) # duration:秒
return
def main():
png_path = 'images'
png_files = os.listdir(png_path)
image_list =[png_path + "/%03d.png" % frame_id for frame_id in range(len(png_files))]
gif_name = 'created_gif.gif'
create_gif(image_list, gif_name)
if __name__ == '__main__':
main()
imageio库有个弊端是好像不能将透明背景的png图像生成透明背景的gif图像
3. pillow
pip install pillow
GitHub:https://github.com/python-pillow/Pillow
官方文档:
https://pillow.readthedocs.io/en/latest/handbook/image-file-formats.html#gif
pillow可以通过设置transparency参数,使GIF背景为透明的。
import os
import random
from PIL import Image, ImageDraw, ImageSequence
def gif2pngs(gif_path, png_path):
"""gif图像拆成若干png帧图"""
img = Image.open(gif_path)
for ind, frame in enumerate(ImageSequence.all_frames(img)):
# 保存每一帧图像
frame.save(os.path.join(png_path, "%03d.png" % ind))
def pngs2gif(png_path, gif_name):
"""png帧图生成gif图像"""
frames = []
png_files = os.listdir(png_path)
for frame_id in range(len(png_files)):
frame = Image.open(os.path.join(png_path, "%03d.png" % frame_id))
frames.append(frame)
# frames.reverse() # 将图像序列逆转
frames[0].save(gif_name, save_all=True, append_images=frames[1:], loop=0, disposal=2)
def draw_gif(gif_name):
"""通过PIL绘制动态图"""
size = 50
i = 0
colors = ['red', 'blue', 'green', 'gray']
# 绘制随机闪现的球
frames = []
while i < 100:
img = Image.new("RGBA", (800, 800), color=(0, 0, 0))
draw = ImageDraw.Draw(img)
x = random.randint(-800, 800)
y = random.randint(-800, 800)
if x-size < 0 or x-size > img.size[0]:
continue
if y-size < 0 or y-size > img.size[1]:
continue
draw.ellipse((x, y, x + size, y + size), fill=colors[random.randint(0, 3)])
frames.append(img)
i += 1
# transparency 透明背景设置,duration单位 毫秒, loop=0无限循环 loop=1循环一次,不设置,不循环
frames[0].save(gif_name, save_all=True, append_images=frames[1:], transparency=0, duration=100, loop=0, disposal=2)
if __name__ == '__main__':
gif2pngs('下班了.gif', 'images')
pngs2gif('images', 'tmp.gif')
draw_gif('ball.gif')
gif2pngs('下班了.gif', 'images')函数执行后会在images保存帧图像
长按二维码关注我们
有趣的灵魂在等你