【问题标题】:PySimpleGUI Graph Displaying an image directlyPySimpleGUI Graph 直接显示图像
【发布时间】:2021-12-24 16:01:27
【问题描述】:

我正在尝试使用 Pysimplegui 及其“图形”组件制作一个应用程序,以便用户可以使用该应用程序在图像上绘制多边形。这是我的代码的一部分:

layout = [[sg.Graph(
    canvas_size=(length, width),
    graph_bottom_left=(0, 0),
    graph_top_right=(length, width),
    key="-GRAPH-",
    change_submits=True,  # mouse click events
    background_color='lightblue',
    drag_submits=True), ],]
window = sg.Window("draw rect on image", layout, finalize=True)
graph = window["-GRAPH-"]

这里的长度和宽度是指我拥有的图像的大小。我知道如何显示图像的唯一方法是通过graph.draw_image(path, location=(0,width)),其中路径是 png 文件的位置。

我的问题是:有没有办法在图形中直接使用图像而不是路径来显示图像。 (即,如果我有一个代表图像的 nd numpy 数组,我是否可以直接让它显示在画布中,而不是先保存为 png 然后加载位置?)。是否有可能完全避免任何形式的节省?

直观地说,graph.draw_image 方法读取路径并打开图像然后显示。应该有一种方法可以避免任何保存并使图形直接显示图像。

【问题讨论】:

    标签: pysimplegui


    【解决方案1】:

    您可以在这里使用选项data,但您需要先将图像从数组转换为数据。

    def draw_image(self, filename=None, data=None, location=(None, None)):
    
    Places an image onto your canvas.  It's a really important method for this element as it enables so much
    
    :param filename: if image is in a file, path and filename for the image. (GIF and PNG only!)
    :type filename:  (str)
    :param data:     if image is in Base64 format or raw? format then use instead of filename
    :type data:      str | bytes
    :param location: the (x,y) location to place image's top left corner
    :type location:  (int, int) | Tuple[float, float]
    :return:         id returned from tkinter that you'll need if you want to manipulate the image
    :rtype:          int | None
    

    数组中的数据可能只是 RGBA 的值,没有图像格式,如 PNG。 所以我把它从数组转换为PIL.Image,然后保存到数据使用io.BytesIO

    示例代码

    from io import BytesIO
    from PIL import Image
    import numpy as np
    import PySimpleGUI as sg
    
    def array_to_data(array):
        im = Image.fromarray(array)
        with BytesIO() as output:
            im.save(output, format="PNG")
            data = output.getvalue()
        return data
    
    font = ("Courier New", 11)
    sg.theme("DarkBlue3")
    sg.set_options(font=font)
    
    im = Image.open("D:/Fandom.png")
    array = np.array(im, dtype=np.uint8)
    data = array_to_data(array)
    
    width, height = 640, 480
    
    layout = [[sg.Graph(
        canvas_size=(width, height),
        graph_bottom_left=(0, 0),
        graph_top_right=(width, height),
        key="-GRAPH-",
        change_submits=True,  # mouse click events
        background_color='lightblue',
        drag_submits=True), ],]
    window = sg.Window("draw rect on image", layout, finalize=True)
    graph = window["-GRAPH-"]
    graph.draw_image(data=data, location=(0, height))
    
    while True:
    
        event, values = window.read()
        if event in (sg.WINDOW_CLOSED, 'Exit'):
            break
        print(event, values)
    
    window.close()
    

    【讨论】:

    • 非常感谢!这适用于单个图像。顺便说一句,是否有可能更快地做到这一点?也就是说,如果我有代表 200 个图像的 200 个数组,运行该方法将需要一段时间。
    • 多线程或者多处理都可以,但是需要自己去寻找答案,比如stackoverflow.com/questions/26294013/…
    • 你认为有可能避免任何形式的节省吗?
    • 只有当图像已经是所需的格式时才有效,例如 base64、PNG、GIF 和 PPM/PGM 格式。
    • 想详细说明一下?我确实有图像采用这些格式的情况。我只想尽我所能避免保存。
    猜你喜欢
    • 2022-01-26
    • 2021-11-01
    • 2015-09-01
    • 2021-11-20
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    相关资源
    最近更新 更多