PySimpleGUI/DemoPrograms/Demo_Img_Viewer.py

118 lines
4.0 KiB
Python
Raw Normal View History

2018-09-27 20:24:09 +00:00
#!/usr/bin/env python
import PySimpleGUI as sg
2018-09-03 20:52:22 +00:00
import os
from PIL import Image, ImageTk
import io
2018-09-03 20:52:22 +00:00
"""
Simple Image Browser based on PySimpleGUI
--------------------------------------------
There are some improvements compared to the PNG browser of the repository:
1. Paging is cyclic, i.e. automatically wraps around if file index is outside
2. Supports all file types that are valid PIL images
3. Limits the maximum form size to the physical screen
4. When selecting an image from the listbox, subsequent paging uses its index
5. Paging performance improved significantly because of using PIL
Dependecies
------------
Python3
2018-09-03 20:52:22 +00:00
PIL
"""
2018-10-08 17:30:33 +00:00
# Get the folder containin:g the images from the user
folder = sg.popup_get_folder('Image folder to open', default_path='')
2018-10-08 17:30:33 +00:00
if not folder:
sg.popup_cancel('Cancelling')
2018-09-03 20:52:22 +00:00
raise SystemExit()
# PIL supported image types
img_types = (".png", ".jpg", "jpeg", ".tiff", ".bmp")
# get list of files in folder
flist0 = os.listdir(folder)
# create sub list of image files (no sub folders, no wrong file types)
fnames = [f for f in flist0 if os.path.isfile(
os.path.join(folder, f)) and f.lower().endswith(img_types)]
2018-09-03 20:52:22 +00:00
num_files = len(fnames) # number of iamges found
if num_files == 0:
sg.popup('No files in folder')
2018-09-03 20:52:22 +00:00
raise SystemExit()
del flist0 # no longer needed
# ------------------------------------------------------------------------------
2018-09-03 20:52:22 +00:00
# use PIL to read data of one image
# ------------------------------------------------------------------------------
def get_img_data(f, maxsize=(1200, 850), first=False):
2018-09-03 20:52:22 +00:00
"""Generate image data using PIL
"""
img = Image.open(f)
img.thumbnail(maxsize)
if first: # tkinter is inactive the first time
bio = io.BytesIO()
img.save(bio, format="PNG")
2018-09-03 20:52:22 +00:00
del img
return bio.getvalue()
return ImageTk.PhotoImage(img)
# ------------------------------------------------------------------------------
2018-09-03 20:52:22 +00:00
# make these 2 elements outside the layout as we want to "update" them later
# initialize to the first file in the list
filename = os.path.join(folder, fnames[0]) # name of first file in list
image_elem = sg.Image(data=get_img_data(filename, first=True))
2018-09-03 20:52:22 +00:00
filename_display_elem = sg.Text(filename, size=(80, 3))
file_num_display_elem = sg.Text('File 1 of {}'.format(num_files), size=(15, 1))
2018-09-03 20:52:22 +00:00
# define layout, show and read the form
col = [[filename_display_elem],
[image_elem]]
2018-09-03 20:52:22 +00:00
col_files = [[sg.Listbox(values=fnames, change_submits=True, size=(60, 30), key='listbox')],
[sg.Button('Next', size=(8, 2)), sg.Button('Prev', size=(8, 2)), file_num_display_elem]]
2018-09-03 20:52:22 +00:00
layout = [[sg.Column(col_files), sg.Column(col)]]
2018-09-03 20:52:22 +00:00
window = sg.Window('Image Browser', layout, return_keyboard_events=True,
location=(0, 0), use_default_focus=False)
2018-09-03 20:52:22 +00:00
# loop reading the user input and displaying image, filename
i = 0
2018-09-03 20:52:22 +00:00
while True:
# read the form
event, values = window.read()
print(event, values)
2018-09-03 20:52:22 +00:00
# perform button and keyboard operations
if event == sg.WIN_CLOSED:
2018-09-03 20:52:22 +00:00
break
elif event in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34'):
2018-09-03 20:52:22 +00:00
i += 1
if i >= num_files:
i -= num_files
filename = os.path.join(folder, fnames[i])
elif event in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33'):
2018-09-03 20:52:22 +00:00
i -= 1
if i < 0:
i = num_files + i
filename = os.path.join(folder, fnames[i])
elif event == 'listbox': # something from the listbox
2018-09-03 20:52:22 +00:00
f = values["listbox"][0] # selected filename
filename = os.path.join(folder, f) # read this file
i = fnames.index(f) # update running index
else:
filename = os.path.join(folder, fnames[i])
# update window with new image
image_elem.update(data=get_img_data(filename, first=True))
2018-09-03 20:52:22 +00:00
# update window with filename
filename_display_elem.update(filename)
2018-09-03 20:52:22 +00:00
# update page display
file_num_display_elem.update('File {} of {}'.format(i+1, num_files))
window.close()