From 65a0eb72724caf4def523e2c792db1e899971878 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 19 Jul 2022 10:15:15 +0000 Subject: [PATCH] [FIX] base: fix autoresize and exclude gif Odoo may resize attachment image with side larger than 1920 pixels. But for animated gifs, this resizement seems to in general increase size file which is not what we want (in some case making it grow from 3MB to 60 MB). So with this change, we only resize and optimize images that are not gifs. Reasoning: pillow doesn't seem to resize GIF (and seems to only increase their size, especially animated GIF, because each frame is not optimized) so we should just not touch them. Note: - currently tiff were not resized (because of a mimetype typo) - currently image dimensions were not resized (from our test, resizing on the dimension does not change the size much, quality is most important). both of these issue have been solved in this commit. opw-2897291 closes odoo/odoo#97083 X-original-commit: 6d903d61adba11c9e46009511fd4065dbc8a9e0c Signed-off-by: Nicolas Lempereur (nle) --- odoo/addons/base/models/ir_attachment.py | 14 ++++++++------ odoo/addons/base/tests/test_ir_attachment.py | 6 ++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/odoo/addons/base/models/ir_attachment.py b/odoo/addons/base/models/ir_attachment.py index 0431efd09d7..5571a456e7a 100644 --- a/odoo/addons/base/models/ir_attachment.py +++ b/odoo/addons/base/models/ir_attachment.py @@ -303,7 +303,7 @@ class IrAttachment(models.Model): def _postprocess_contents(self, values): ICP = self.env['ir.config_parameter'].sudo().get_param - supported_subtype = ICP('base.image_autoresize_extensions', 'png,jpeg,gif,bmp,tif').split(',') + supported_subtype = ICP('base.image_autoresize_extensions', 'png,jpeg,bmp,tiff').split(',') mimetype = values['mimetype'] = self._compute_mimetype(values) _type, _subtype = mimetype.split('/') @@ -315,20 +315,22 @@ class IrAttachment(models.Model): max_resolution = ICP('base.image_autoresize_max_px', '1920x1920') if str2bool(max_resolution, True): try: - img = fn_quality = False + img = False if is_raw: img = ImageProcess(values['raw'], verify_resolution=False) - fn_quality = img.image_quality else: # datas img = ImageProcess(base64.b64decode(values['datas']), verify_resolution=False) - fn_quality = lambda **args: base64.b64encode(img.image_quality(**args)) w, h = img.image.size nw, nh = map(int, max_resolution.split('x')) if w > nw or h > nh: - img.resize(nw, nh) + img = img.resize(nw, nh) quality = int(ICP('base.image_autoresize_quality', 80)) - values[is_raw and 'raw' or 'datas'] = fn_quality(quality=quality) + image_data = img.image_quality(quality=quality) + if is_raw: + values['raw'] = image_data + else: + values['datas'] = base64.b64encode(image_data) except UserError as e: # Catch error during test where we provide fake image # raise UserError(_("This file could not be decoded as an image file. Please try with a different file.")) diff --git a/odoo/addons/base/tests/test_ir_attachment.py b/odoo/addons/base/tests/test_ir_attachment.py index bf20afcfee6..960775456c0 100644 --- a/odoo/addons/base/tests/test_ir_attachment.py +++ b/odoo/addons/base/tests/test_ir_attachment.py @@ -205,6 +205,12 @@ class TestIrAttachment(TransactionCase): attach.raw = img_bin self.assertApproximately(attach.raw, fullsize) + # no resize of gif + self.env['ir.config_parameter'].set_param('base.image_autoresize_max_px', '0x0') + gif_bin = b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;' + attach.raw = gif_bin + self.assertEqual(attach.raw, gif_bin) + def test_11_copy(self): """ Copying an attachment preserves the data