kivy:可以使用缓冲区作为图像源吗?

Posted

技术标签:

【中文标题】kivy:可以使用缓冲区作为图像源吗?【英文标题】:kivy: possible to use buffer as image source? 【发布时间】:2014-01-21 05:33:32 【问题描述】:

我有如下代码,它可以从一些现有图像中生成一个新图像。

from PIL import Image as pyImage

def create_compound_image(back_image_path, fore_image_path, fore_x_position):

    back_image_size = get_image_size(back_image_path)
    fore_image_size = get_image_size(fore_image_path)

    new_image_width = (fore_image_size[0] / 2) + back_image_size[0]
    new_image_height = fore_image_size[1] + back_image_size[1]

    new_image = create_new_image_canvas(new_image_width, new_image_height)

    back_image = pyImage.open(back_image_path)
    fore_image = pyImage.open(fore_image_path)

    new_image.paste(back_image, (0, 0), mask = None) 
    new_image.paste(fore_image, (fore_x_position, back_image_size[1]), mask = None)

    return new_image

在代码的后面,我有这样的东西:

from kivy.uix.image import Image
img = Image(source = create_compound_image(...))

如果我执行上述操作,我会收到 Image.source only accepts string/unicode 的消息。

如果我从新图像创建StringIO.StringIO() 对象,并尝试将其用作源,则错误消息与上述相同。如果我使用 StringIO 对象的 getvalue() 方法的输出作为源,则消息是 source must be encoded string without NULL bytes, not str

在创建 kivy Image 对象时,使用create_compound_image() 函数的输出作为源的正确方法是什么?

【问题讨论】:

【参考方案1】:

您似乎只想将两个图像合并为一个,实际上您可以使用 Texture.create 创建纹理并使用 Texture.blit_buffer 将数据blit 到特定位置。

from kivy.core.image import Image
from kivy.graphics import Texture

bkimg = Image(bk_img_path)
frimg = Image(fr_img_path)

new_size = ((frimg.texture.size[0]/2) + bkimg.texture.size[0],
            frimg.texture.size[1] + bkimg.texture.size[1])

tex = Texture.create(size=new_size)
tex.blit_buffer(pbuffer=bkimg.texture.pixels, pos=(0, 0), size=bkimg.texture.size)
tex.blit_buffer(pbuffer=frimg.texture.pixels, pos=(fore_x_position, bkimg.texture.size[1]), size=frimg.texture.size)

现在你可以在任何地方直接使用这个纹理,比如::

from kivy.uix.image import Image
image = Image()
image.texture = tex

【讨论】:

我对这种方法有疑问。粘贴到“tex”时,似乎不是粘贴到空白表面,程序尝试用“bkimg”或“frimg”中的像素填充“tex”;反过来,这似乎扩展了“tex”。如果按照预期粘贴到空白画布中,有没有办法让它发挥作用?谢谢! 没关系 - 使用 pygame Surfaces 处理了它。再次感谢! 很高兴看到您成功了。我似乎从 blit_buffer 中省略了 size 参数,这在这种情况下对实现您的目标很有用。【参考方案2】:

source 是一个StringProperty 并且需要一个文件路径。这就是为什么当您尝试传递 PIL.Image 对象、StringIO 对象或图像的字符串表示时出现错误的原因。这不是框架想要的。至于从StringIO获取图片,这里之前讨论过:

https://groups.google.com/forum/#!topic/kivy-users/l-3FJ2mA3qI https://github.com/kivy/kivy/issues/684

您还可以尝试更简单、快速和肮脏的方法 - 只需将图像保存为 tmp 文件并以正常方式读取即可。

【讨论】:

谢谢,尼卡金。我想避免使用 tmp 文件方法,以避免耗时的 I/O 操作。感谢您的链接 - 虽然有用,但它看起来确实有点令人费解;我想纹理方法(如下所示)可能是解决这个特定问题的更可行的选择。

以上是关于kivy:可以使用缓冲区作为图像源吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 DOMXPath 在 Li 类中提取图像源吗? [复制]

确定何时播放缓冲区而不在 OpenAL 中轮询源

无标题

无标题

将图像从缓冲区转换为前端显示(颤振)

如何将缓冲区图像上传到 cloudinary?