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

时间:2014-01-03 14:07:41

标签: image buffer kivy

我有以下几行代码,它们会从一些现有图像中生成一个新图像。

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()函数的输出作为源的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

source是一个StringProperty,期待一个文件路径。这就是您尝试传递PIL.Image对象,StringIO对象或图像的字符串表示时出错的原因。这不是框架想要的。至于从StringIO获取图像,之前已讨论过:

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