用Python实现播放gif文件
在Python中,你可以使用第三方库Pillow(PIL)来加载和展示 GIF 文件。并实现“暂停”和“继续”控制功能。
Pillow是Python社区中最受欢迎的图像处理库之一,可以轻松地完成各种图像处理任务,它易于学习和使用,并且具有良好的文档和社区支持。Pillow基于PIL库进行了更新和改进(最初是PIL的一个分支,后来发展独立,并超越了它)。
Windows系统电脑中pillow库的安装,在cmd中输入如下命令后回车即可:
pip install pillow
若你的电脑上安装了多个Python版本,你可以为特定版本的Python安装,例如我的电脑中安装了多个Python版本,要在Python 3.10版本中安装,并使用清华的镜像,cmd命令行中,输入如下命令
py -3.10 -m pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
需要注意的是pillow库安装成功后,导包时要用PIL来导入,而不是用pillow【这里使用 PIL 导入,但实际上使用的是 Pillow 库,这里的 PIL 可以看做是 Pillow 库的简称】。如:
import PIL
from PIL import Image
关于第三方库Pillow(PIL)的更多介绍可见https://blog.csdn.net/cnds123/article/details/126141838
先看出效果图:
【提示:实际运行画面是动态的。】
注意,某些GIF可能使用了特殊的编码或格式特性,这些特性可能不被Pillow(PIL)库完全支持。
源码如下:
from PIL import Image, ImageTk
import tkinter as tk
from tkinter import filedialog
class GIFPlayer:
def __init__(self, master):
self.master = master
self.frames = []
self.delay = []
self.is_paused = False
self.gif_path = None
# 创建画布和按钮
self.canvas = tk.Canvas(master, width=400, height=400, bg='grey')
self.canvas.pack()
# 创建用于显示GIF的区域
self.gif_area = self.canvas.create_rectangle(20, 20, 380, 380, outline='black')
self.open_button = tk.Button(master, text="Open", command=self.open_file)
self.open_button.pack()
self.pause_button = tk.Button(master, text="Pause/Resume", command=self.toggle_pause)
self.pause_button.pack()
def open_file(self):
self.gif_path = filedialog.askopenfilename(title="Open GIF", filetypes=[("GIF Files", "*.gif")])
if not self.gif_path:
return
self.gif = Image.open(self.gif_path)
self.original_width, self.original_height = self.gif.size
self.original_frames = [] # 新增列表以保存原始的Image帧
# 加载GIF帧
try:
for i in range(self.gif.n_frames):
self.gif.seek(i)
frame = self.gif.copy()
if 'gif_frame' in frame.info:
frame.info['gif_frame'] = i
self.original_frames.append(frame) # 保存原始的Image帧
self.frames.append(ImageTk.PhotoImage(frame))
self.delay.append(self.gif.info['duration'])
except EOFError:
pass
self.frame_index = 0
self.scale_and_animate(0)
def scale_and_animate(self, frame_index):
# 获取指定区域的大小
area_width = 360 #
area_height = 360
# 计算缩放因子
scale_w = area_width / self.original_width
scale_h = area_height / self.original_height
scale = min(scale_w, scale_h)
# 调整图像大小
new_width = int(self.original_width * scale)
new_height = int(self.original_height * scale)
# 对原始帧应用缩放
frame = self.original_frames[frame_index].resize((new_width, new_height), Image.ANTIALIAS)
self.photo = ImageTk.PhotoImage(frame) # 更新图片对象
self.canvas.delete('gif')
self.canvas.create_image(20, 20, anchor=tk.NW, image=self.photo, tags='gif')
if not self.is_paused:
self.frame_index = (self.frame_index + 1) % len(self.original_frames)
self.master.after(self.delay[frame_index], lambda: self.scale_and_animate(self.frame_index))
def toggle_pause(self):
self.is_paused = not self.is_paused
if self.is_paused:
self.pause_button.config(text="Resume")
else:
self.pause_button.config(text="Pause")
# 恢复播放时立即调用 scale_and_animate
self.scale_and_animate(self.frame_index)
if __name__ == '__main__':
root = tk.Tk()
player = GIFPlayer(root)
root.mainloop()