【问题标题】:Display PIL Image on Kivy Canvas在 Kivy 画布上显示 PIL 图像
【发布时间】:2018-08-12 05:53:08
【问题描述】:

我找不到任何关于如何在 Kivy 画布上显示 PIL 图像的文档。

Rectangle(source=image) give TypeError: 'Image' object has no attribute '__getitem__'

由于其他图像处理,我需要使用枕头图像。我什至尝试将图像加载到纹理中,然后将纹理应用到画布上,但后来我不知道如何将格式转换为兼容的格式。关于如何在纹理和画布上加载图像的 Kivy 文档几乎不存在。

【问题讨论】:

    标签: python kivy python-imaging-library


    【解决方案1】:
    from kivy.core.image import Image as CoreImage
    from kivy.uix.image import Image as kiImage
    from PIL import Image, ImageDraw, ImageFont
    from io import BytesIO
    
    canvas_img = Image.new('RGB', (240, 120), color=(255, 255, 255))
    (do stuff to canvas_img)
    data = BytesIO()
    canvas_img.save(data, format='png')
    data.seek(0) # yes you actually need this
    im = CoreImage(BytesIO(data.read()), ext='png')
    self.beeld = kiImage() # only use this line in first code instance
    self.beeld.texture = im.texture
    

    【讨论】:

    • 哈,使用 BytesIO 正是我解决问题的方法。但是,当您忘记先查找(0)时,它会产生一些惊人的内存问题。
    【解决方案2】:

    在下面的示例中,它演示了使用 PIL Image 来操作图像并将其呈现为 Kivy Image 小部件的 sourcetexturecanvas .

    示例

    main.py

    ​​>
    from kivy.app import App
    from kivy.uix.tabbedpanel import TabbedPanel
    from kivy.uix.image import CoreImage
    from kivy.lang import Builder
    
    from PIL import Image
    
    kv = Builder.load_string('''
    #:kivy 1.11.0
    
    <RootWidget>:
        img: img
        img3: img3
        img4: img4
        do_default_tab: False
    
        TabbedPanelItem:
            text: 'PIL Image'
    
            Screen:
                RelativeLayout:
                    Image:
                        id: img
                        pos_hint: {"left": 1, 'bottom': 1}
                        size_hint: 0.5, 1
                        allow_stretch: True
    
                RelativeLayout:
                    Image:
                        id: img3
                        pos_hint: {"right": 1, 'bottom': 1}
                        size_hint: 0.5, 1
                        allow_stretch: True
    
        TabbedPanelItem:
            text: 'canvas'
    
            Screen:
                FloatLayout:
                    Image:
                        id: img4
                        keep_data: True
                        allow_stretch: True
                        canvas.before:
                            Color:
                                rgba: 0, 0, 0, 1  # Black
                            Rectangle:
                                pos: self.pos
                                size: self.size
    
    
    ''')
    
    
    class RootWidget(TabbedPanel):
    
        def __init__(self, **kwargs):
            super(RootWidget, self).__init__(**kwargs)
            iw = Image.open("./DSC08518.JPG")   # Use PIL.Image
            iw.save('./phase.jpg')
            gray = iw.convert('1')
            gray.save('./gray_im.jpg')
            self.img.source = './phase.jpg'
            self.img3.texture = CoreImage('./gray_im.jpg').texture
            self.img4.source = './gray_im.jpg'
    
    
    class KivyPILApp(App):
        title = "Kivy & PIL Demo"
    
        def build(self):
            return RootWidget()
    
    
    if __name__ == "__main__":
        KivyPILApp().run()
    

    输出

    【讨论】:

    • 很好的信息,但不是我的想法。我可以使用 PIL 加载图像,然后将其作为纹理属性应用,而无需使用 CoreImage 保存并重新打开它吗?保存并重新打开似乎非常浪费。
    猜你喜欢
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多