简体   繁体   English

使用blit_buffer和pos参数在Kivy中对纹理进行动画处理

[英]Animate texture in Kivy using blit_buffer and pos parameter

I have some image data that I'm blitting to a texture and displaying in Kivy. 我有一些图像数据会流向纹理并以Kivy显示。 The image data is the same width, with a greater height than the widget. 图像数据的宽度相同,但高度大于窗口小部件。 After the texture is created, I want to animate the y position of it for a scrolling effect. 创建纹理后,我想对其的y位置进行动画处理以获得滚动效果。

Previously, I had been blitting the entire buffer to the texture, and animating the position of the widget itself. 以前,我一直在将整个缓冲区分配给纹理,并为小部件本身的位置设置动画。 However, the buffer data is occasionally larger than the maximum supported texture size of my GPU, and nothing displays on the screen. 但是,缓冲区数据有时大于我的GPU支持的最大纹理大小,并且屏幕上没有任何显示。

I figured a better approach would be to only blit the section of the source buffer I need, and leave the texture the same size as the widget. 我认为更好的方法是只对我需要的源缓冲区部分进行着色,并保留与小部件相同的纹理大小。

After looking at the documentation for Kivy, I discovered there's a pos parameter. 在查看Kivy的文档后,我发现有一个pos参数。 I figured I could use an animated property for the document ypos in the call to blit_buffer, but when I tried it, nothing displayed again. 我认为可以在对blit_buffer的调用中为文档ypos使用一个动画属性,但是当我尝试它时,什么也没有显示。

I switched the pos parameter to (0, 100) to see if my usage of the parameter did what I expected, and it still didn't display. 我将pos参数切换为(0,100),以查看我对参数的使用是否达到了我的预期,并且仍然没有显示。 Switching it to (0, 0) works as expected. 将其切换为(0,0)可以正常工作。

Am I using blit_buffer() correctly? 我是否正确使用blit_buffer()? What's the best way to blit only a portion of an image data buffer? 只对图像数据缓冲区的一部分进行blit的最佳方法是什么?

EDIT: I recreated this issue with a standalone script: 编辑:我用一个独立的脚本重新创建了此问题:

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()

It seems the issue was that the pos argument of Texture.blit_buffer() specifies the destination coordinates of the image data, rather than the source coordinates. 似乎问题在于Texture.blit_buffer()的pos参数指定了图像数据的目标坐标,而不是源坐标。

I ended up solving my problem by using PIL to crop the image data, then creating a tiling renderer that contains multiple textures each tile is blit to. 我最终通过使用PIL裁剪图像数据解决了我的问题,然后创建了一个平铺渲染器,该平铺渲染器包含将每个平铺图块绑定到的多个纹理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM