如何使用PIL在Tkinter中正确显示在线的.webp格式动图
问题成因
- PIL的
Image.open()方法加载WebP动图时默认仅读取第一帧数据,WebP动图本身是包含多帧图像+每帧播放时长的序列资源,未主动遍历读取的情况下只能获取到首帧内容。 - Tkinter原生的
Label控件和ImageTk.PhotoImage仅支持静态单帧展示,没有内置动图逐帧刷新的逻辑,不会自动更新显示内容。
可行解决方法
手动解析WebP动图的所有帧,记录每帧的播放时长,再通过Tkinter的after()方法定时更新Label显示的图像即可实现动效,完整可运行代码如下:
import tkinter import urllib.request from io import BytesIO from PIL import Image, ImageTk root = tkinter.Tk() # 加载WebP动图资源 u = urllib.request.urlopen("你的webp动图链接") raw_data = u.read() u.close() im = Image.open(BytesIO(raw_data)) # 预解析所有帧和对应播放时长 frames = [] durations = [] try: while True: # 缩放每帧到目标尺寸 frame = ImageTk.PhotoImage(im.resize((470, 210))) frames.append(frame) # 读取当前帧播放时长,默认100ms防止取不到值 durations.append(im.info.get("duration", 100)) im.seek(im.tell() + 1) except EOFError: # 所有帧读取完成 pass label = tkinter.Label(root, image=frames[0]) label.pack() current_frame = 0 def update_frame(): global current_frame current_frame = (current_frame + 1) % len(frames) label.config(image=frames[current_frame]) # 按当前帧的时长定时调用更新 root.after(durations[current_frame], update_frame) # 启动帧更新循环 update_frame() # 把frames列表绑定到root属性防止被垃圾回收导致图像空白 root.frames = frames root.mainloop()
- 需提前安装支持WebP格式的Pillow库,可执行
pip install pillow完成安装。
内容的提问来源于stack exchange,提问作者Code2D
相关产品推荐
相关产品推荐

