打开一个 'PNG' 文件,然后是 numpy,然后是 base64,但是图像没有显示?

Open a 'PNG' file, then numpy, then base64, but image not shown?

尝试做一些图像处理,加载图像以在 Graph 上显示,但没有显示。 Win10/Python3.7.6/PySimpleGUI 4.16.0/Numpy 1.18.1

我通过PIL.Image载入一张图片,转成numpy数组,再转成base64,在Graph中DrawImage,但是什么都不显示。我已经为此工作好几次了,一切都很好。检查了几个小时,但没有任何帮助。谁能帮我找出我错过或错误的地方?

我发现了一些东西,

  1. 我打开了,im.show() OK
  2. im.shape 是正确的,例如 (200, 150, 3) 对于 150(宽)x 200(高)x RGB 图像。
  3. im_np显示不同的数据,好像还可以。
  4. im_64 显示字节串
  5. draw是None,应该是一个id。
  6. 为 DrawingImage 设置文件名选项,就可以了

我这里需要用到numpy做一些图像处理,所以需要转换。

import base64
import numpy as np
import PySimpleGUI as sg
from PIL import Image

filename = 'D:/Disk.png'
im = Image.open(filename)
width, height = im.size
im_np = np.array(im)    # It is necesary for future process
im_64 = base64.b64encode(im_np)

def Graph(key):
    return sg.Graph(im.size, graph_bottom_left=(0, 0),
                    graph_top_right=(width, height), key=key)

layout = [[Graph('GRAPH')]]
window = sg.Window('Graph', layout=layout, finalize=True)

draw = window.FindElement('GRAPH').DrawImage(
    data=im_64, location=(width/2, height/2))           # It failed
    # filename=filename, location=(width/2, height/2))  # It working well

while True:

    event, values = window.read()

    if event == None:
        break

window.close()

您需要传递 PNG "as binary" 编码的 base64,而不是编码为 base64 的 numpy 数组。

PySimpleGUI documentation看不是很清楚,但是当data作为base64传递时,数据不是base64的原始数据,而是base64的图像文件内容。

  • 将 PNG 文件读取为二进制文件:

    with open(filename, 'rb') as binary_file:
        #Read image file as binary data
        data = binary_file.read()
    
  • 将二进制表示编码为 base64:

    im_64 = base64.b64encode(data)
    
  • im_64 作为 data 传递:

    draw = window.FindElement('GRAPH').DrawImage(
        data=im_64, location=(width/2, height/2))          # Works
    

这是一个代码示例:

import base64
import numpy as np
import PySimpleGUI as sg
from PIL import Image

#filename = 'D:/Disk.png'
filename = 'chelsea.png'

with open(filename, 'rb') as binary_file:
    #Read image file as binary data
    data = binary_file.read()

im = Image.open(filename)
width, height = im.size
im_np = np.array(im)    # It is necesary for future process
#im_64 = base64.b64encode(im_np)

# Encode the PNG binary representation 
im_64 = base64.b64encode(data)

def Graph(key):
    return sg.Graph(im.size, graph_bottom_left=(0, 0),
                    graph_top_right=(width, height), key=key)

layout = [[Graph('GRAPH')]]
window = sg.Window('Graph', layout=layout, finalize=True)

draw = window.FindElement('GRAPH').DrawImage(
    data=im_64, location=(width/2, height/2))          # Works
    #filename=filename, location=(width/2, height/2))  # It working well

while True:

    event, values = window.read()

    if event == None:
        break

window.close()

如果要显示im_np,可以使用下面post的解决方法。

  • im_np 作为 PNG 图像写入字符串:

    im_pil = Image.fromarray(im_np)
    
    with io.BytesIO() as output:
        im_pil.save(output, format="PNG")
        data = output.getvalue()
    
    im_64 = base64.b64encode(data)
    

结果: