Откройте файл PNG, затем numpy, затем base64, но изображение не отображается? - PullRequest
1 голос
/ 13 марта 2020

Попробуйте выполнить некоторую обработку изображения, загрузите изображение для отображения на графике, но ничего не отображается. Win10 / Python 3.7.6 / PySimple GUI 4.16.0 / Numpy 1.18.1

I Загрузить изображение с помощью PIL.Image, преобразовать его в массив numpy, затем в base64, DrawImage в Graph, но ничего не показывает. Я работал над этим несколько раз, и все в порядке. проверил пару часов, но ничего не помогло. Может ли кто-нибудь помочь мне выяснить, где я пропустил или ошибся?

Что-то, что я нашел,

  1. im open, im.show () OK
  2. im.shape правильно, например (200, 150, 3) для изображения 150 (ширина) x 200 (высота) x RGB.
  3. im_np показывает разные данные, кажется, что все в порядке.
  4. im_64 показано строка байтов
  5. draw имеет значение None, это должен быть идентификатор.
  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()

1 Ответ

1 голос
/ 13 марта 2020

Вам необходимо передать PNG "как двоичный" кодированный base64, а не массив numpy, закодированный как base64.

Это не так ясно из PySimple GUI документации , но при передаче 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)
    
  • Pass 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, вы можете использовать решение из следующей записи .

  • Запись 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)
    

Результат:
enter image description here

...