使用 blit_buffer 和 pos 参数在 Kivy 中动画纹理

Animate texture in Kivy using blit_buffer and pos parameter

我有一些图像数据,我正在将其写入纹理并在 Kivy 中显示。图像数据宽度相同,但高度大于小部件。创建纹理后,我想为它的 y 位置设置动画以实现滚动效果。

之前,我一直在将整个缓冲区 blit 到纹理,并为小部件本身的位置设置动画。但是,缓冲数据偶尔会大于我的GPU支持的最大纹理大小,屏幕上什么也没有显示。

我认为更好的方法是只 blit 我需要的源缓冲区部分,并使纹理与小部件大小相同。

在查看了 Kivy 的文档后,我发现有一个 pos 参数。我想我可以在调用 blit_buffer 时为文档 ypos 使用动画 属性,但是当我尝试它时,没有再次显示。

我把pos参数改成(0, 100)看我对参数的使用是否符合我的预期,还是没有显示。将其切换为 (0, 0) 会按预期工作。

我是否正确使用了 blit_buffer()?仅 blit 图像数据缓冲区的一部分的最佳方法是什么?

编辑:我用独立脚本重现了这个问题:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.image import Image
from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle

import array

class MyWidget(Widget):
    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)

        texture = Texture.create(size=(512, 512))
        buf = [int(x * 255 / (512*512*3)) for x in range(512*512*3)]
        buf = array.array('B', buf).tostring()

        texture.blit_buffer(
            buf,
            colorfmt='rgb',
            bufferfmt='ubyte',
            pos=(0, 100)
        )

        with self.canvas:
            Rectangle(texture=texture, pos=self.pos, size=(512, 512))

class MyApp(App):
    def build(self):
        return MyWidget()

if __name__ == '__main__':
    MyApp().run()

问题似乎是 Texture.blit_buffer() 的 pos 参数指定了图像数据的目标坐标,而不是源坐标。

我最终解决了我的问题,方法是使用 PIL 裁剪图像数据,然后创建一个平铺渲染器,其中包含多个纹理,每个平铺被 blit 到。