-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDemo_image.py
163 lines (133 loc) · 5.71 KB
/
Demo_image.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import PySimpleGUI as sg
import PIL
from PIL import Image
import io
import base64
import os
"""
Using PIL with PySimpleGUI
This image viewer uses both a thumbnail creation function and an image resizing function that
you may find handy to include in your code.
Copyright 2020 PySimpleGUI.org
"""
THUMBNAIL_SIZE = (200,200)
IMAGE_SIZE = (800,800)
THUMBNAIL_PAD = (1,1)
ROOT_FOLDER = r'/home/plasmalab/Documents/Moritz/04_segmentation/pytorch-deeplab-xception/test_images'
screen_size = sg.Window.get_screen_size()
thumbs_per_row = int(screen_size[0]/(THUMBNAIL_SIZE[0]+THUMBNAIL_PAD[0])) - 1
thumbs_rows = int(screen_size[1]/(THUMBNAIL_SIZE[1]+THUMBNAIL_PAD[1])) - 1
THUMBNAILS_PER_PAGE = (thumbs_per_row, thumbs_rows)
def make_square(im, min_size=256, fill_color=(0, 0, 0, 0)):
x, y = im.size
size = max(min_size, x, y)
new_im = Image.new('RGBA', (size, size), fill_color)
new_im.paste(im, (int((size - x) / 2), int((size - y) / 2)))
return new_im
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)
: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 display_image_window(filename):
try:
layout = [[sg.Image(data=convert_to_bytes(filename, IMAGE_SIZE), enable_events=True)]]
e,v = sg.Window(filename, layout, modal=True, element_padding=(0,0), margins=(0,0)).read(close=True)
except Exception as e:
print(f'** Display image error **', e)
return
def make_thumbnails(flist):
layout = [[]]
for row in range(THUMBNAILS_PER_PAGE[1]):
row_layout = []
for col in range(THUMBNAILS_PER_PAGE[0]):
try:
f = flist[row*THUMBNAILS_PER_PAGE[1] + col]
# row_layout.append(sg.B(image_data=convert_to_bytes(f, THUMBNAIL_SIZE), k=(row,col), pad=THUMBNAIL_PAD))
row_layout.append(sg.B('',k=(row,col), size=(0,0), pad=THUMBNAIL_PAD,))
except:
pass
layout += [row_layout]
layout += [[sg.B(sg.SYMBOL_LEFT + ' Prev', size=(10,3), k='-PREV-'), sg.B('Next '+sg.SYMBOL_RIGHT, size=(10,3), k='-NEXT-'), sg.B('Exit', size=(10,3)), sg.Slider((0,100), orientation='h', size=(50,15), enable_events=True, key='-SLIDER-')]]
return sg.Window('Thumbnails', layout, element_padding=(0, 0), margins=(0, 0), finalize=True, grab_anywhere=False, location=(0,0), return_keyboard_events=True)
EXTS = ('png', 'jpg', 'gif')
def display_images(t_win, offset, files):
currently_displaying = {}
row = col = 0
while True:
if offset + 1 > len(files) or row == THUMBNAILS_PER_PAGE[1]:
break
f = files[offset]
currently_displaying[(row, col)] = f
try:
t_win[(row, col)].update(image_data=convert_to_bytes(f, THUMBNAIL_SIZE, True))
except Exception as e:
print(f'Error on file: {f}', e)
col = (col + 1) % THUMBNAILS_PER_PAGE[0]
if col == 0:
row += 1
offset += 1
if not (row == 0 and col == 0):
while row != THUMBNAILS_PER_PAGE[1]:
t_win[(row, col)].update(image_data=sg.DEFAULT_BASE64_ICON)
currently_displaying[(row, col)] = None
col = (col + 1) % THUMBNAILS_PER_PAGE[0]
if col == 0:
row += 1
return offset, currently_displaying
def main():
files = [os.path.join(ROOT_FOLDER, f) for f in os.listdir(ROOT_FOLDER) if True in [f.endswith(e) for e in EXTS]]
files.sort()
t_win = make_thumbnails(files)
offset, currently_displaying = display_images(t_win, 0, files)
# offset = THUMBNAILS_PER_PAGE[0] * THUMBNAILS_PER_PAGE[1]
# currently_displaying = {}
while True:
win, event, values = sg.read_all_windows()
print(event, values)
if win == sg.WIN_CLOSED: # if all windows are closed
break
if event == sg.WIN_CLOSED or event == 'Exit':
break
if isinstance(event, tuple):
display_image_window(currently_displaying.get(event))
continue
elif event == '-SLIDER-':
offset = int(values['-SLIDER-']*len(files)/100)
event = '-NEXT-'
else:
t_win['-SLIDER-'].update(offset * 100 / len(files))
if event == '-NEXT-' or event.endswith('Down'):
offset, currently_displaying = display_images(t_win, offset, files)
elif event == '-PREV-' or event.endswith('Up'):
offset -= THUMBNAILS_PER_PAGE[0]*THUMBNAILS_PER_PAGE[1]*2
if offset < 0:
offset = 0
offset, currently_displaying = display_images(t_win, offset, files)
if __name__ == '__main__':
main()