[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) <nle@odoo.com>
This commit is contained in:
Nicolas Lempereur
2022-07-29 15:53:43 +02:00
parent 1de5a22dfa
commit 65a0eb7272
2 changed files with 14 additions and 6 deletions
+8 -6
View File
@@ -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."))
@@ -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