diff --git a/addons/web/models/base_document_layout.py b/addons/web/models/base_document_layout.py index 36d8a511dfc..ff685b32073 100644 --- a/addons/web/models/base_document_layout.py +++ b/addons/web/models/base_document_layout.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import markupsafe -from PIL import Image from markupsafe import Markup from odoo import api, fields, models, tools @@ -14,6 +13,10 @@ except ImportError: # If the `sass` python library isn't found, we fallback on the # `sassc` executable in the path. libsass = None +try: + from PIL.Image import Resampling +except ImportError: + from PIL import Image as Resampling DEFAULT_PRIMARY = '#000000' DEFAULT_SECONDARY = '#000000' @@ -204,7 +207,7 @@ class BaseDocumentLayout(models.TransientModel): # Converts to RGBA (if already RGBA, this is a noop) image_converted = image.convert('RGBA') - image_resized = image_converted.resize((w, h), resample=Image.NEAREST) + image_resized = image_converted.resize((w, h), resample=Resampling.NEAREST) colors = [] for color in image_resized.getcolors(w * h): diff --git a/odoo/tools/image.py b/odoo/tools/image.py index 55ef4690b8f..8db8ada4b9b 100644 --- a/odoo/tools/image.py +++ b/odoo/tools/image.py @@ -7,6 +7,10 @@ import io from PIL import Image, ImageOps # We can preload Ico too because it is considered safe from PIL import IcoImagePlugin +try: + from PIL.Image import Transpose, Palette, Resampling +except ImportError: + Transpose = Palette = Resampling = Image from random import randrange @@ -30,16 +34,16 @@ FILETYPE_BASE64_MAGICWORD = { EXIF_TAG_ORIENTATION = 0x112 # The target is to have 1st row/col to be top/left # Note: rotate is counterclockwise -EXIF_TAG_ORIENTATION_TO_TRANSPOSE_METHODS = { # Initial side on 1st row/col: - 0: [], # reserved - 1: [], # top/left - 2: [Image.FLIP_LEFT_RIGHT], # top/right - 3: [Image.ROTATE_180], # bottom/right - 4: [Image.FLIP_TOP_BOTTOM], # bottom/left - 5: [Image.FLIP_LEFT_RIGHT, Image.ROTATE_90], # left/top - 6: [Image.ROTATE_270], # right/top - 7: [Image.FLIP_TOP_BOTTOM, Image.ROTATE_90], # right/bottom - 8: [Image.ROTATE_90], # left/bottom +EXIF_TAG_ORIENTATION_TO_TRANSPOSE_METHODS = { # Initial side on 1st row/col: + 0: [], # reserved + 1: [], # top/left + 2: [Transpose.FLIP_LEFT_RIGHT], # top/right + 3: [Transpose.ROTATE_180], # bottom/right + 4: [Transpose.FLIP_TOP_BOTTOM], # bottom/left + 5: [Transpose.FLIP_LEFT_RIGHT, Transpose.ROTATE_90],# left/top + 6: [Transpose.ROTATE_270], # right/top + 7: [Transpose.FLIP_TOP_BOTTOM, Transpose.ROTATE_90],# right/bottom + 8: [Transpose.ROTATE_90], # left/bottom } # Arbitrary limit to fit most resolutions, including Nokia Lumia 1020 photo, @@ -134,7 +138,7 @@ class ImageProcess(): if quality: if output_image.mode != 'P': # Floyd Steinberg dithering by default - output_image = output_image.convert('RGBA').convert('P', palette=Image.WEB, colors=256) + output_image = output_image.convert('RGBA').convert('P', palette=Palette.WEB, colors=256) if output_format == 'JPEG': opt['optimize'] = True opt['quality'] = quality or 95 @@ -171,7 +175,7 @@ class ImageProcess(): asked_width = max_width or (w * max_height) // h asked_height = max_height or (h * max_width) // w if asked_width != w or asked_height != h: - self.image.thumbnail((asked_width, asked_height), Image.LANCZOS) + self.image.thumbnail((asked_width, asked_height), Resampling.LANCZOS) if self.image.width != w or self.image.height != h: self.operationsCount += 1 return self