[IMP] Compress resized /website/image's

Refactored and fixed tools.image_resize_image() that converted to RGBA
after making thumbnails, resulting in bad looking picture in case the
source is in 'P' mode (indexed palette)
This commit is contained in:
Fabien Meghazi 2014-09-07 11:41:46 +02:00
parent bc5e6fa2cb
commit 3f27066019
2 changed files with 31 additions and 11 deletions

View File

@ -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']

View File

@ -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.