# pylint:disable=invalid-name
import functools
from pytoolbox import module
_all = module.All(globals())
from PIL import Image # noqa pylint:disable=wrong-import-position
TRANSPOSE_SEQUENCES = {
None: [],
1: [],
2: [Image.FLIP_LEFT_RIGHT],
3: [Image.ROTATE_180],
4: [Image.FLIP_TOP_BOTTOM],
5: [Image.FLIP_LEFT_RIGHT, Image.ROTATE_90],
6: [Image.ROTATE_270],
7: [Image.FLIP_TOP_BOTTOM, Image.ROTATE_90],
8: [Image.ROTATE_90]
}
[docs]def get_orientation(image, orientation_tag=0x0112, no_exif_default=None, no_key_default=None):
exif = getattr(image, '_getexif', lambda: None)()
try:
return no_exif_default if exif is None else exif[orientation_tag]
except KeyError:
return no_key_default
[docs]def apply_orientation( # pylint:disable=dangerous-default-value
image,
get_orientation=get_orientation, # pylint:disable=redefined-outer-name
sequences=TRANSPOSE_SEQUENCES
):
"""Credits: https://stackoverflow.com/questions/4228530/pil-thumbnail-is-rotating-my-image."""
orientation = get_orientation(image)
return functools.reduce(lambda i, op: i.transpose(op), sequences.get(orientation, []), image)
[docs]def open(file_or_path): # pylint:disable=redefined-builtin
image = Image.open(file_or_path)
try:
image.load()
except IOError as ex:
if 'truncated' not in str(ex):
raise
return image
[docs]def remove_transparency(image, background=(255, 255, 255)):
"""
Return a RGB image with an alpha mask applied to picture + background.
If image is already in RGB, then its a no-op.
"""
if image.mode == 'RGB':
return image # No-op
alpha = image.convert('RGBA').getchannel('A')
new_image = Image.new('RGB', image.size, background)
new_image.paste(image.convert('RGB'), mask=alpha)
return new_image
[docs]def save(image, *args, **kwargs):
kwargs.setdefault('exif', image.info.get('exif', b''))
return image.save(*args, **kwargs)
__all__ = _all.diff(globals())