[IMP] web_editor: upload a JPEG too when uploading a WEBP

The library used to generate PDFs does not support the WEBP image
format. For those images to be included in reports, they need to be
converted. For security reasons, this conversion cannot be done on the
server, therefore it was decided to keep an already converted copy of
such images.

This commit converts uploaded WEBP images to JPEG and uploads them both
so that the report generation can use the JPEG instead.

task-2774352

Part-of: odoo/odoo#85494
This commit is contained in:
Benoit Socias
2023-07-15 05:10:45 +02:00
parent 4d3819b221
commit c035d0003d
3 changed files with 46 additions and 1 deletions
+9 -1
View File
@@ -542,7 +542,7 @@ class Web_Editor(http.Controller):
return files_data_by_bundle
@http.route('/web_editor/modify_image/<model("ir.attachment"):attachment>', type="json", auth="user", website=True)
def modify_image(self, attachment, res_model=None, res_id=None, name=None, data=None, original_id=None, mimetype=None):
def modify_image(self, attachment, res_model=None, res_id=None, name=None, data=None, original_id=None, mimetype=None, alt_data=None):
"""
Creates a modified copy of an attachment and returns its image_src to be
inserted into the DOM.
@@ -561,6 +561,14 @@ class Web_Editor(http.Controller):
if name:
fields['name'] = name
attachment = attachment.copy(fields)
if alt_data:
attachment.create({
'name': attachment.name + '.jpg',
'datas': alt_data,
'res_id': attachment.id,
'res_model': 'ir_attachment',
'mimetype': 'image/jpeg',
})
if attachment.url:
# Don't keep url if modifying static attachment because static images
# are only served from disk and don't fallback to attachments.
@@ -122,6 +122,29 @@ export const uploadService = {
file.hasError = true;
file.errorMessage = attachment.error;
} else {
if (attachment.mimetype === 'image/webp') {
// Generate alternate format for reports.
const image = document.createElement('img');
image.src = `data:image/webp;base64,${dataURL.split(',')[1]}`;
await new Promise(resolve => image.addEventListener('load', resolve));
const canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(255, 255, 255)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, 0, 0);
const altDataURL = canvas.toDataURL('image/jpeg', 0.75);
await rpc('/web_editor/attachment/add_data', {
'name': file.name.replace(/\.webp$/, '.jpg'),
'data': altDataURL.split(',')[1],
'res_id': attachment.id,
'res_model': 'ir.attachment',
'is_image': true,
'width': 0,
'quality': 0,
}, {xhr});
}
file.uploaded = true;
await onUploaded(attachment);
}
@@ -975,12 +975,26 @@ const Wysiwyg = Widget.extend({
// Modifying an image always creates a copy of the original, even if
// it was modified previously, as the other modified image may be used
// elsewhere if the snippet was duplicated or was saved as a custom one.
let altData = undefined;
if (el.dataset.mimetype === 'image/webp') {
// Generate alternate format for reports.
const image = document.createElement('img');
image.src = isBackground ? el.dataset.bgSrc : el.getAttribute('src');
await new Promise(resolve => image.addEventListener('load', resolve));
const canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
altData = canvas.toDataURL('image/jpeg', 0.75).split(',')[1];
}
const newAttachmentSrc = await this._rpc({
route: `/web_editor/modify_image/${encodeURIComponent(el.dataset.originalId)}`,
params: {
res_model: resModel,
res_id: parseInt(resId),
data: (isBackground ? el.dataset.bgSrc : el.getAttribute('src')).split(',')[1],
alt_data: altData,
mimetype: el.dataset.mimetype,
name: (el.dataset.fileName ? el.dataset.fileName : null),
},