如何在Kivy中控制zip压缩包内PNG序列帧动画的播放、快进及倒放
Kivy PNG序列帧播放器控制实现方案
Kivy的Image组件加载zip序列帧后,可通过操作其内部_coreimage对象的anim_index属性控制当前显示的帧,自带的动画播放逻辑仅支持正向,要实现自定义控制需手动接管帧切换逻辑,以下是可直接运行的实现代码:
from kivy.core.window import Window from kivy.clock import Clock from kivy.lang import Builder from kivymd.app import MDApp Window.size = (440, 760) kv = ''' MDScreen: MDGridLayout: cols: 1 Image: id: display_image source: 'video/sophia.zip' anim_delay: 0 # 禁用默认自动播放 anim_reset: True size_hint_y:None height: 480 on_texture: app.init_frame() # 纹理加载完成后初始化帧位置 ''' class PNGPlayer(MDApp): def build(self): self.root = Builder.load_string(kv) self.img = self.root.ids.display_image self.total_frames = 90 # 已知每个zip有90张图,也可加载完成后动态获取 self.play_direction = 1 # 1正向播放,-1反向播放,0暂停 # 启动自定义播放定时器,30fps self.play_event = Clock.schedule_interval(self.update_frame, 1/30) # 绑定触摸滑动事件 self.root.bind(on_touch_move=self.on_swipe) return self.root def init_frame(self): # 序列加载完成后定位到第45帧(索引从0开始计数,所以对应值为44) if hasattr(self.img._coreimage, 'anim_index'): self.img._coreimage.anim_index = 44 self.play_direction = 0 # 默认暂停在初始帧 def update_frame(self, dt): if self.play_direction == 0: return # 更新帧索引,超出边界自动循环 new_idx = self.img._coreimage.anim_index + self.play_direction if new_idx >= self.total_frames: new_idx = 0 elif new_idx < 0: new_idx = self.total_frames - 1 self.img._coreimage.anim_index = new_idx def on_swipe(self, instance, touch): # 过滤垂直滑动,只处理水平滑动操作 if abs(touch.dx) < abs(touch.dy): return # 滑动步长,数值越大快进/快退幅度越大,可自行调整 step = 3 if touch.dx > 0: # 右滑快进 new_idx = self.img._coreimage.anim_index + step else: # 左滑快退 new_idx = self.img._coreimage.anim_index - step # 边界钳位,避免索引越界 new_idx = max(0, min(new_idx, self.total_frames-1)) self.img._coreimage.anim_index = new_idx # 滑动时默认暂停自动播放,也可根据需求去掉这行 self.play_direction = 0 # 扩展控制方法,可直接绑定到UI按钮实现播放控制 def play_forward(self): self.play_direction = 1 def play_backward(self): self.play_direction = -1 def pause(self): self.play_direction = 0 if __name__== '__main__': PNGPlayer().run()
关键逻辑说明
- 动态总帧数获取:如果不确定zip内的图片总数,可在
init_frame方法中通过len(self.img._coreimage._images)获取加载完成的总帧数,替换硬编码的90即可。 - 播放速度调整:修改
Clock.schedule_interval的第二个参数即可调整播放帧率,数值越小播放速度越快。 - 交互扩展:如果需要增加进度条、跳转指定帧等功能,直接修改
anim_index属性即可实现对应效果。
内容的提问来源于stack exchange,提问作者Ian Rajkumar
相关产品推荐
相关产品推荐

