Commit 30161fc5 authored by Gabriel Monnerat's avatar Gabriel Monnerat

erp5_document_scanner: Optimize code to reduce image size before crop

parent 4c3ab064
...@@ -211,7 +211,7 @@ ...@@ -211,7 +211,7 @@
text: 'New Page', text: 'New Page',
// Do not allow to show again the current image // Do not allow to show again the current image
disabled: (len === gadget.state.page - 1), disabled: (len === gadget.state.page - 1),
class: 'new-btn ui-btn-icon-left ui-icon-plus' "class": 'new-btn ui-btn-icon-left ui-icon-plus'
})); }));
return domsugar('ol', {"class": "thumbnail-list"}, thumbnail_dom_list); return domsugar('ol', {"class": "thumbnail-list"}, thumbnail_dom_list);
}); });
...@@ -303,28 +303,31 @@ ...@@ -303,28 +303,31 @@
return image_capture.takePhoto({imageWidth: capabilities.imageWidth.max}); return image_capture.takePhoto({imageWidth: capabilities.imageWidth.max});
}) })
.push(function (blob) { .push(function (blob) {
return createImageBitmap(blob); return RSVP.all([
createImageBitmap(blob),
jIO.util.readBlobAsDataURL(blob)
]);
}) })
.push(function (bitmap) { .push(function (result_list) {
var canvas = domsugar('canvas', {'class': 'canvas'}); var bitmap = result_list[0],
canvas = domsugar('canvas', {'class': 'canvas'});
canvas.width = bitmap.width; canvas.width = bitmap.width;
canvas.height = bitmap.height; canvas.height = bitmap.height;
canvas.getContext('2d').drawImage(bitmap, 0, 0); canvas.getContext('2d').drawImage(bitmap, 0, 0);
return canvas; return [canvas, result_list[1].target.result];
}) })
.push(function (canvas) { .push(function (result_list) {
var new_canvas; var new_canvas,
canvas = result_list[0],
data_url = result_list[1];
gadget.detached_promise_dict.media_stream.cancel('Not needed anymore, as captured'); gadget.detached_promise_dict.media_stream.cancel('Not needed anymore, as captured');
if (settings.brightness || settings.contrast || settings.enable_greyscale || settings.compression) { if (settings.brightness || settings.contrast || settings.enable_greyscale || settings.compression) {
new_canvas = domsugar('canvas', {'class': 'canvas', new_canvas = domsugar('canvas', {'class': 'canvas'});
'width': canvas.width,
'height': canvas.height
});
return new RSVP.Queue() return new RSVP.Queue()
.push(function (result) { .push(function (result) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
// XXX the correct usage is `new Caman()` but the library does not support it // XXX the correct usage is `new Caman()` but the library does not support it
caman(new_canvas, canvas.toDataURL(), function () { caman(new_canvas, data_url, function () {
if (settings.brightness && settings.brightness !== 0) { if (settings.brightness && settings.brightness !== 0) {
this.brightness(settings.brightness); this.brightness(settings.brightness);
} }
...@@ -347,16 +350,16 @@ ...@@ -347,16 +350,16 @@
return RSVP.all([ return RSVP.all([
gadget.getTranslationList(["Delete", "Save"]), gadget.getTranslationList(["Delete", "Save"]),
new Promise(function (resolve) { new Promise(function (resolve) {
resolve(canvas); resolve(canvas.toDataURL("image/jpeg"));
}), }),
buildPreviousThumbnailDom(gadget) buildPreviousThumbnailDom(gadget)
]); ]);
}) })
.push(function (result_list) { .push(function (result_list) {
var canvas = result_list[1], var data_url = result_list[1],
img = domsugar("img", {"src": data_url}),
defer = RSVP.defer(); defer = RSVP.defer();
// Prepare the cropper canvas // Prepare the cropper canvas
div = domsugar('div', {'class': 'camera'}, [ div = domsugar('div', {'class': 'camera'}, [
domsugar('div', {'class': 'camera-header'}, [ domsugar('div', {'class': 'camera-header'}, [
domsugar('h4', [ domsugar('h4', [
...@@ -364,7 +367,7 @@ ...@@ -364,7 +367,7 @@
domsugar('label', {'class': 'page-number', text: gadget.state.page}) domsugar('label', {'class': 'page-number', text: gadget.state.page})
]) ])
]), ]),
canvas, img,
domsugar('div', {'class': 'edit-picture'}, [ domsugar('div', {'class': 'edit-picture'}, [
domsugar('button', {type: 'button', domsugar('button', {type: 'button',
'class': 'reset-btn ui-btn-icon-left ui-icon-times', 'class': 'reset-btn ui-btn-icon-left ui-icon-times',
...@@ -382,7 +385,7 @@ ...@@ -382,7 +385,7 @@
// For now, it needs to access dom element size // For now, it needs to access dom element size
gadget.element.replaceChild(div, gadget.element.firstElementChild); gadget.element.replaceChild(div, gadget.element.firstElementChild);
addDetachedPromise(gadget, 'cropper', addDetachedPromise(gadget, 'cropper',
handleCropper(canvas, handleCropper(img,
gadget.state.preferred_cropped_canvas_data, gadget.state.preferred_cropped_canvas_data,
defer.resolve)); defer.resolve));
return defer.promise; return defer.promise;
...@@ -477,7 +480,6 @@ ...@@ -477,7 +480,6 @@
return selectMediaDevice(gadget.state.device_id, false) return selectMediaDevice(gadget.state.device_id, false)
.push(function (device_id) { .push(function (device_id) {
return gadget.changeState({ return gadget.changeState({
dialog_method: options.dialog_method,
store_new_image_cropped_method: options.store_new_image_cropped_method, store_new_image_cropped_method: options.store_new_image_cropped_method,
active_process: default_value.active_process, active_process: default_value.active_process,
image_list: default_value.image_list, image_list: default_value.image_list,
......
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>981.57848.5692.33382</string> </value> <value> <string>981.58568.65411.58828</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -262,7 +262,7 @@ ...@@ -262,7 +262,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1581860732.16</float> <float>1581903960.55</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
import json
from base64 import decodestring
portal = context.getPortalObject()
translateString = portal.Base_translateString
gadget_data = json.loads(document_scanner_gadget)
image_str = decodestring(gadget_data.pop("input_value"))
preferred_cropped_canvas_data = gadget_data["preferred_cropped_canvas_data"] or {}
selection_mapping = portal.portal_selections.getSelectionParamsFor(
context.Base_getDocumentScannerSelectionName(),
REQUEST=context.REQUEST) or {}
http_user_agent = context.REQUEST["HTTP_USER_AGENT"]
selection_mapping[http_user_agent] = preferred_cropped_canvas_data or {}
portal.portal_selections.setSelectionParamsFor(
context.Base_getDocumentScannerSelectionName(),
selection_mapping,
context.REQUEST
)
if not image_str:
if batch_mode:
if active_process_url:
return portal.restrictedTraverse(active_process_url)
return None
return context.Base_renderForm('Base_viewUploadDocumentFromCameraDialog',
message=translateString('Nothing to capture'))
active_process, _ = context.Base_postDataToActiveResult(
active_process_url,
image_str)
# We need it to fill the form rendered by renderjs
context.REQUEST.form["your_active_process_url"] = active_process.getRelativeUrl()
# We remove it to reduce the size of the response
context.REQUEST.form.pop("field_your_document_scanner_gadget")
context.REQUEST.form.pop('document_scanner_gadget')
if batch_mode:
return active_process
return context.Base_renderForm('Base_viewUploadDocumentFromCameraDialog',
message=translateString('Captured'))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>classification=None, synchronous_metadata_discovery=None, cancel_url=None, batch_mode=False, editable_mode=1, group=None, publication_section=None, document_scanner_gadget=None, active_process_url=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_storeDocumentFromCameraInActiveProcess</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -7,6 +7,20 @@ translateString = portal.Base_translateString ...@@ -7,6 +7,20 @@ translateString = portal.Base_translateString
active_process_url = data_dict.pop("active_process") active_process_url = data_dict.pop("active_process")
image_list = data_dict.pop("image_list") image_list = data_dict.pop("image_list")
preferred_cropped_canvas_data = data_dict.pop("preferred_cropped_canvas_data") or {}
selection_mapping = portal.portal_selections.getSelectionParamsFor(
context.Base_getDocumentScannerSelectionName(),
REQUEST=context.REQUEST) or {}
http_user_agent = context.REQUEST["HTTP_USER_AGENT"]
selection_mapping[http_user_agent] = preferred_cropped_canvas_data or {}
portal.portal_selections.setSelectionParamsFor(
context.Base_getDocumentScannerSelectionName(),
selection_mapping,
context.REQUEST
)
# Avoid to pass huge images to the activity # Avoid to pass huge images to the activity
kw.pop("your_document_scanner_gadget", None) kw.pop("your_document_scanner_gadget", None)
......
...@@ -165,7 +165,7 @@ ...@@ -165,7 +165,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: [(\'dialog_method\', \'Base_storeDocumentFromCameraInActiveProcess\'), (\'preferred_image_settings_data\', context.Base_getPreferredImageSettingsFromPreference()), (\'preferred_cropped_canvas_data\', context.Base_getPreferredCropperSettingsFromSelection()), ("store_new_image_cropped_method", \'Base_storeNewImageCropped\')]</string> </value> <value> <string>python: [(\'preferred_image_settings_data\', context.Base_getPreferredImageSettingsFromPreference()), (\'preferred_cropped_canvas_data\', context.Base_getPreferredCropperSettingsFromSelection()), ("store_new_image_cropped_method", \'Base_storeNewImageCropped\')]</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment