diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 949e276b3b0..a339bcb9c3e 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -25,8 +25,7 @@ except ImportError: import openerp from openerp.osv import orm, osv, fields -from openerp.tools import html_escape as escape -from openerp.tools import ustr as ustr +from openerp.tools import html_escape as escape, ustr, image_resize_and_sharpen from openerp.tools.safe_eval import safe_eval from openerp.addons.web.http import request @@ -589,8 +588,16 @@ class website(osv.osv): if w < max_w and h < max_h: response.data = data else: - image.thumbnail((max_w, max_h), Image.ANTIALIAS) - image.save(response.stream, image.format) + image_format = image.format + size = (max_w, max_h) + image = image_resize_and_sharpen(image, size) + + if image_format == 'PNG': + image.convert('P').save(response.stream, optimize=True, format='PNG') + elif image.format == 'JPEG': + image.save(response.stream, quality=80, optimize=True, format='JPG') + else: + image.save(response.stream, format=image_format) # invalidate content-length computed by make_conditional as # writing to response.stream does not do it (as of werkzeug 0.9.3) del response.headers['Content-Length'] diff --git a/openerp/tools/image.py b/openerp/tools/image.py index 93458fb9408..afa12ced511 100644 --- a/openerp/tools/image.py +++ b/openerp/tools/image.py @@ -88,13 +88,7 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file return base64_source if image.size != size: - # create a thumbnail: will resize and keep ratios, then sharpen for better looking result - image.thumbnail(size, Image.ANTIALIAS) - sharpener = ImageEnhance.Sharpness(image.convert('RGBA')) - resized_image = sharpener.enhance(2.0) - # create a transparent image for background and paste the image on it - image = Image.new('RGBA', size, (255, 255, 255, 0)) - image.paste(resized_image, ((size[0] - resized_image.size[0]) / 2, (size[1] - resized_image.size[1]) / 2)) + image = image_resize_and_sharpen(image, size) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") @@ -102,6 +96,25 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file image.save(background_stream, filetype) return background_stream.getvalue().encode(encoding) +def image_resize_and_sharpen(image, size, factor=2.0): + """ + Create a thumbnail by resizing while keeping ratio. + A sharpen filter is applied for a better looking result. + + :param image: PIL.Image.Image() + :param size: 2-tuple(width, height) + :param factor: Sharpen factor (default: 2.0) + """ + if image.mode != 'RGBA': + image = image.convert('RGBA') + image.thumbnail(size, Image.ANTIALIAS) + sharpener = ImageEnhance.Sharpness(image) + resized_image = sharpener.enhance(factor) + # create a transparent image for background and paste the image on it + image = Image.new('RGBA', size, (255, 255, 255, 0)) + image.paste(resized_image, ((size[0] - resized_image.size[0]) / 2, (size[1] - resized_image.size[1]) / 2)) + return image + def image_resize_image_big(base64_source, size=(1204, 1024), encoding='base64', filetype=None, avoid_if_small=True): """ Wrapper on image_resize_image, to resize images larger than the standard 'big' image size: 1024x1024px.