Merge pull request #6085 from PySimpleGUI/Dev-latest

Added zoom and subsample parms to PIL function (was recently supplied…
This commit is contained in:
PySimpleGUI 2022-12-07 10:07:16 -05:00 committed by GitHub
commit 1c4574908b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 41 additions and 27 deletions

View File

@ -13,51 +13,65 @@ import random
This function is your gateway to using any format of image (not just PNG & GIF) and to 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. resize / convert it so that it can be used with the Button and Image elements.
Copyright 2020 PySimpleGUI.org Copyright 2020, 2022 PySimpleGUI.org
""" """
def make_square(im, min_size=256, fill_color=(0, 0, 0, 0)): def make_square(im, fill_color=(0, 0, 0, 0)):
x, y = im.size x, y = im.size
size = max(min_size, x, y) size = max(x, y)
new_im = Image.new('RGBA', (size, size), fill_color) new_im = Image.new('RGBA', (size, size), fill_color)
new_im.paste(im, (int((size - x) / 2), int((size - y) / 2))) new_im.paste(im, (int((size - x) / 2), int((size - y) / 2)))
return new_im return new_im
def convert_to_bytes(file_or_bytes, resize=None, fill=False):
def convert_to_bytes(source, size=(None, None), subsample=None, zoom=None, fill=False):
""" """
Will convert into bytes and optionally resize an image that is a file or a base64 bytes object. 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 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 :param source: either a string filename or a bytes base64 image object
:type file_or_bytes: (Union[str, bytes]) :type source: (Union[str, bytes])
:param resize: optional new size :param size: optional new size (width, height)
:type resize: (Tuple[int, int] or None) :type size: (Tuple[int, int] or None)
:param fill: If True then the image is filled/padded so that the image is not distorted :param subsample: change the size by multiplying width and height by 1/subsample
:type subsample: (int)
:param zoom: change the size by multiplying width and height by zoom
:type zoom: (int)
:param fill: If True then the image is filled/padded so that the image is square
:type fill: (bool) :type fill: (bool)
:return: (bytes) a byte-string object :return: (bytes) a byte-string object
:rtype: (bytes) :rtype: (bytes)
""" """
if isinstance(file_or_bytes, str): if isinstance(source, str):
img = PIL.Image.open(file_or_bytes) image = Image.open(source)
elif isinstance(source, bytes):
image = Image.open(io.BytesIO(base64.b64decode(source)))
else: else:
try: image = PIL.Image.open(io.BytesIO(source))
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 width, height = image.size
if resize:
new_width, new_height = resize scale = None
scale = min(new_height / cur_height, new_width / cur_width) if size != (None, None):
img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.ANTIALIAS) new_width, new_height = size
if fill: scale = min(new_height/height, new_width/width)
if resize is not None: elif subsample is not None:
img = make_square(img, resize[0]) scale = 1/subsample
elif zoom is not None:
scale = zoom
resized_image = image.resize((int(width * scale), int(height * scale)), Image.ANTIALIAS) if scale is not None else image
if fill and scale is not None:
resized_image = make_square(resized_image)
# encode a PNG formatted version of image into BASE64
with io.BytesIO() as bio: with io.BytesIO() as bio:
img.save(bio, format="PNG") resized_image.save(bio, format="PNG")
del img contents = bio.getvalue()
return bio.getvalue() encoded = base64.b64encode(contents)
return encoded
def random_image(): def random_image():
return random.choice(sg.EMOJI_BASE64_LIST) return random.choice(sg.EMOJI_BASE64_LIST)