You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:39:02