Commit 28b9d317 authored by Romain Courteaud's avatar Romain Courteaud

erp5_document_scanner: add glfx support

Use the GPU to speed up the image manipulation process.
parent 9e8adf0f
......@@ -19,6 +19,7 @@
<script type="text/javascript" src="cropper.min.js"></script>
<script type="text/javascript" src="domsugar.js"></script>
<script type="text/javascript" src="caman.full.min.js"></script>
<script type="text/javascript" src="glfx.js"></script>
<script type="text/javascript" src="gadget_document_scanner.js"></script>
<title>Gadget Document Scanner</title>
</head>
......
......@@ -242,7 +242,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>982.7390.34742.27767</string> </value>
<value> <string>982.46775.50354.51694</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1582765422.37</float>
<float>1585665387.68</float>
<string>UTC</string>
</tuple>
</state>
......
/*jslint indent: 2, unparam: true, bitwise: true */
/*global rJS, RSVP, window, document, navigator, Cropper, Promise, JSON, jIO,
promiseEventListener, domsugar, createImageBitmap, FormData, Caman,
FileReader, DataView, URL*/
FileReader, DataView, URL, fx*/
(function (rJS, RSVP, window, document, navigator, Cropper, Promise, JSON, jIO,
promiseEventListener, domsugar, createImageBitmap, FormData, caman,
FileReader, DataView, URL) {
FileReader, DataView, URL, fx) {
"use strict";
//////////////////////////////////////////////////
......@@ -109,6 +109,29 @@
return new RSVP.Promise(waitForStream, canceller);
}
function handleGfx(canvas, settings) {
var webgl_canvas = fx.canvas(),
texture = webgl_canvas.texture(canvas),
tmp;
// apply the ink filter
tmp = webgl_canvas.draw(texture);
if ((settings.brightness && settings.brightness !== 0) ||
(settings.contrast && settings.contrast !== 0)) {
tmp.brightnessContrast(
(settings.brightness || 0) / 100,
(settings.contrast || 0) / 100
);
}
if (settings.enable_greyscale) {
tmp.hueSaturation(0, -1);
}
tmp.update();
return webgl_canvas;
}
function handleCaman(canvas, settings) {
var local_caman;
......@@ -142,7 +165,7 @@
this.render(function () {
// XXX canceller should be called automatically ?
canceller();
resolve();
resolve(canvas);
});
} catch (error) {
canceller();
......@@ -427,30 +450,57 @@
orientation = result;
var expected_width = settings.maximum_width,
bitmap_options,
div;
bitmap_options;
// If orientation is correct, return the original blob
// and size is small
// no color correction is expected
// and no color correction is expected
if (((orientation < 2) || (8 < orientation)) &&
((!expected_width) || (original_width < expected_width)) &&
((!expected_width) ||
((original_width < expected_width) && (original_height < expected_width))) &&
(!(settings.brightness || settings.contrast || settings.enable_greyscale))) {
return blob;
}
if ((!!expected_width) && (expected_width < original_width)) {
bitmap_options = {
resizeWidth: expected_width,
// resizeHeight: expected_height,
resizeQuality: 'high'
};
}
// Else, transform the image
return new RSVP.Queue(createImageBitmap(blob, bitmap_options))
return new RSVP.Queue(createImageBitmap(blob))
.push(function (bitmap) {
// Check if image dimension must be changed
// It is mandatory to check the bitmap info,
// as the image could be rotated
var canvas,
webgl_context,
higher_dimension_key,
higher_dimension_value;
if (bitmap.width < bitmap.height) {
higher_dimension_key = 'resizeHeight';
higher_dimension_value = bitmap.height;
} else {
higher_dimension_key = 'resizeWidth';
higher_dimension_value = bitmap.width;
}
canvas = document.createElement('canvas');
webgl_context = canvas.getContext('webgl');
expected_width = Math.min(
expected_width || webgl_context.getParameter(webgl_context.MAX_TEXTURE_SIZE),
webgl_context.getParameter(webgl_context.MAX_TEXTURE_SIZE) - 1
);
if ((!!expected_width) && (expected_width < higher_dimension_value)) {
bitmap_options = {
resizeQuality: 'high'
};
bitmap_options[higher_dimension_key] = expected_width;
return createImageBitmap(blob, bitmap_options);
}
return bitmap;
})
.push(function (bitmap) {
var height = bitmap.height,
width = bitmap.width,
canvas = domsugar('canvas'),
......@@ -458,9 +508,9 @@
// Caman expect the canvas to be in a container
// in order to replace it when resizing
div = domsugar('div', [canvas]);
domsugar('div', [canvas]);
if (4 < orientation && orientation < 9) {
if ((4 < orientation) && (orientation < 9)) {
canvas.width = height;
canvas.height = width;
} else {
......@@ -499,11 +549,13 @@
ctx.drawImage(bitmap, 0, 0);
if (settings.brightness || settings.contrast || settings.enable_greyscale) {
return handleCaman(canvas, settings);
return handleGfx(canvas, settings);
// return handleCaman(canvas, settings);
}
return canvas;
})
.push(function () {
return promiseCanvasToBlob(div.firstElementChild);
.push(function (final_canvas) {
return promiseCanvasToBlob(final_canvas);
});
});
}
......@@ -951,4 +1003,4 @@
}(rJS, RSVP, window, document, navigator, Cropper, Promise, JSON, jIO,
promiseEventListener, domsugar, createImageBitmap, FormData, Caman,
FileReader, DataView, URL));
\ No newline at end of file
FileReader, DataView, URL, fx));
\ No newline at end of file
......@@ -244,7 +244,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>982.58526.37480.14609</string> </value>
<value> <string>982.59651.45192.29798</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -262,7 +262,7 @@
</tuple>
<state>
<tuple>
<float>1585660747.23</float>
<float>1585728228.5</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -7,6 +7,8 @@ url_list = [
"cropper.min.css",
"cropper.min.js",
"caman.full.min.js"
"caman.full.min.js",
"glfx.js"
]
return url_list
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Cacheable__manager_id</string> </key>
<value> <string>must_revalidate_http_cache</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>glfx.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>glfx.js</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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