Merge pull request #3827 from PySimpleGUI/Dev-latest
Initial checkin of PIL Demo
This commit is contained in:
commit
c2d72439df
|
@ -0,0 +1,96 @@
|
|||
import PySimpleGUI as sg
|
||||
import PIL
|
||||
from PIL import Image
|
||||
import io
|
||||
import base64
|
||||
|
||||
"""
|
||||
Using PIL with PySimpleGUI - for Images and Buttons
|
||||
|
||||
The reason for this demo is to give you this nice PIL based function - convert_to_bytes
|
||||
|
||||
This function is your gateway to using any format of image (not just PNG & GIF) and to
|
||||
resize / convert it so that it can be used with the Button and Image elements.
|
||||
|
||||
Copyright 2020 PySimpleGUI.org
|
||||
"""
|
||||
|
||||
def convert_to_bytes(file_or_bytes, resize=None, fill=False):
|
||||
'''
|
||||
Will convert into bytes and optionally resize an image that is a file or a base64 bytes object.
|
||||
Turns into PNG format in the process so that can be displayed by tkinter
|
||||
:param file_or_bytes: either a string filename or a bytes base64 image object
|
||||
:type file_or_bytes: (Union[str, bytes])
|
||||
:param resize: optional new size
|
||||
:type resize: (Tuple[int, int] or None)
|
||||
:param fill: If True then the image is filled/padded so that the image is not distorted
|
||||
:type fill: (bool)
|
||||
:return: (bytes) a byte-string object
|
||||
:rtype: (bytes)
|
||||
'''
|
||||
if isinstance(file_or_bytes, str):
|
||||
img = PIL.Image.open(file_or_bytes)
|
||||
else:
|
||||
try:
|
||||
img = PIL.Image.open(io.BytesIO(base64.b64decode(file_or_bytes)))
|
||||
except Exception as e:
|
||||
dataBytesIO = io.BytesIO(file_or_bytes)
|
||||
img = PIL.Image.open(dataBytesIO)
|
||||
|
||||
cur_width, cur_height = img.size
|
||||
if resize:
|
||||
new_width, new_height = resize
|
||||
scale = min(new_height / cur_height, new_width / cur_width)
|
||||
img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.ANTIALIAS)
|
||||
if fill:
|
||||
img = make_square(img, THUMBNAIL_SIZE[0])
|
||||
with io.BytesIO() as bio:
|
||||
img.save(bio, format="PNG")
|
||||
del img
|
||||
return bio.getvalue()
|
||||
|
||||
|
||||
def make_toolbar():
|
||||
layout = [[sg.T('❎', enable_events=True, key='Exit')]]
|
||||
for i in range(6):
|
||||
layout += [[sg.B(image_data = convert_to_bytes(sg._random_error_icon(), (30,30))),
|
||||
sg.B(image_data = convert_to_bytes(sg._random_error_icon(), (30,30)))]]
|
||||
return sg.Window('', layout, element_padding=(0,0), margins=(0,0), finalize=True, no_titlebar=True, grab_anywhere=True)
|
||||
|
||||
def main():
|
||||
|
||||
image = sg._random_error_icon()
|
||||
size = (60,60)
|
||||
image = convert_to_bytes(image, size)
|
||||
|
||||
layout = [[sg.Button('+', size=(4,2)), sg.Button('-', size=(4,2)), sg.B('Next', size=(4,2)), sg.T(size, size=(10,1), k='-SIZE-')],
|
||||
[sg.Image(data=image, k='-IMAGE-')],
|
||||
[sg.Button(image_data=image, key='-BUTTON IMAGE-')],]
|
||||
|
||||
window = sg.Window('Window Title', layout, finalize=True)
|
||||
toolbar = make_toolbar()
|
||||
|
||||
while True: # Event Loop
|
||||
event_window, event, values = sg.read_all_windows()
|
||||
if event == sg.WIN_CLOSED or event == 'Exit':
|
||||
break
|
||||
if event == '+':
|
||||
size = (size[0]+20, size[1]+20)
|
||||
elif event == '-':
|
||||
if size[0] > 20:
|
||||
size = (size[0]-20, size[1]-20)
|
||||
elif event in ('Next', '-BUTTON IMAGE-'):
|
||||
image = sg._random_error_icon()
|
||||
elif event_window == toolbar:
|
||||
image = event_window[event].ImageData
|
||||
|
||||
# Resize image and update the window
|
||||
image = convert_to_bytes(image, size)
|
||||
window['-IMAGE-'].update(data=image)
|
||||
window['-BUTTON IMAGE-'].update(image_data=image)
|
||||
window['-SIZE-'].update(size)
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue