diff --git a/example/css/styles.css b/example/css/styles.css
index 1239c5b..6e5a419 100644
--- a/example/css/styles.css
+++ b/example/css/styles.css
@@ -21,8 +21,7 @@
@import url("https://fonts.googleapis.com/css?family=Ubuntu:400,700|Cabin+Condensed:400,600");
/* line 1, ../sass/_viewport.scss */
#interactive.viewport {
- width: 640px;
- height: 480px;
+ max-width: 100%;
}
.input-field {
diff --git a/example/file_input.html b/example/file_input.html
index 06ca78b..f75d1da 100644
--- a/example/file_input.html
+++ b/example/file_input.html
@@ -8,7 +8,7 @@
-
+
diff --git a/src/decoder/barcode_decoder.js b/src/decoder/barcode_decoder.js
index cbd9eab..6bff4e7 100644
--- a/src/decoder/barcode_decoder.js
+++ b/src/decoder/barcode_decoder.js
@@ -26,7 +26,7 @@ const READERS = {
i2of5_reader: I2of5Reader
};
export default {
- create: function(config, inputImageWrapper) {
+ create: function(config) {
var _canvas = {
ctx: {
frequency: null,
@@ -136,7 +136,7 @@ export default {
* @param {Array} line
* @param {Number} angle
*/
- function getExtendedLine(line, angle, ext) {
+ function getExtendedLine(inputImageWrapper, line, angle, ext) {
function extendLine(amount) {
var extension = {
y: amount * Math.sin(angle),
@@ -169,7 +169,7 @@ export default {
}];
}
- function tryDecode(line) {
+ function tryDecode(inputImageWrapper, line) {
var result = null,
i,
barcodeLine = Bresenham.getBarcodeLine(inputImageWrapper, line[0], line[1]);
@@ -204,7 +204,7 @@ export default {
* @param {Array} line
* @param {Number} lineAngle
*/
- function tryDecodeBruteForce(box, line, lineAngle) {
+ function tryDecodeBruteForce(inputImageWrapper, box, line, lineAngle) {
var sideLength = Math.sqrt(Math.pow(box[1][0] - box[0][0], 2) + Math.pow((box[1][1] - box[0][1]), 2)),
i,
slices = 16,
@@ -226,7 +226,7 @@ export default {
line[1].y += extension.x;
line[1].x -= extension.y;
- result = tryDecode(line);
+ result = tryDecode(inputImageWrapper, line);
}
return result;
}
@@ -243,7 +243,7 @@ export default {
* @param {Object} box The area to search in
* @returns {Object} the result {codeResult, line, angle, pattern, threshold}
*/
- function decodeFromBoundingBox(box) {
+ function decodeFromBoundingBox(inputImageWrapper, box) {
var line,
lineAngle,
ctx = _canvas.ctx.overlay,
@@ -259,14 +259,14 @@ export default {
line = getLine(box);
lineLength = getLineLength(line);
lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
- line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.1));
+ line = getExtendedLine(inputImageWrapper, line, lineAngle, Math.floor(lineLength * 0.1));
if (line === null){
return null;
}
- result = tryDecode(line);
+ result = tryDecode(inputImageWrapper, line);
if (result === null) {
- result = tryDecodeBruteForce(box, line, lineAngle);
+ result = tryDecodeBruteForce(inputImageWrapper, box, line, lineAngle);
}
if (result === null) {
@@ -287,17 +287,14 @@ export default {
}
return {
- decodeFromBoundingBox: function(box) {
- return decodeFromBoundingBox(box);
- },
- decodeFromBoundingBoxes: function(boxes) {
+ decodeFromBoundingBoxes: function(inputImageWrapper, boxes) {
var i, result,
barcodes = [],
multiple = config.multiple;
for ( i = 0; i < boxes.length; i++) {
const box = boxes[i];
- result = decodeFromBoundingBox(box) || {};
+ result = decodeFromBoundingBox(inputImageWrapper, box) || {};
result.box = box;
if (multiple) {
diff --git a/src/input/ImageSource.js b/src/input/ImageSource.js
new file mode 100644
index 0000000..76b0346
--- /dev/null
+++ b/src/input/ImageSource.js
@@ -0,0 +1,84 @@
+import {findTagsInObjectURL} from './exif_helper';
+
+export function fromImage(input, constraints = {width: 800, height: 800, channels: 3}) {
+ var $image = null;
+ var src = null;
+ if (typeof input === 'string') {
+ // data or url, or queryString
+ $image = new Image();
+ src = input;
+ } else if (input instanceof HTMLImageElement) {
+ $image = input;
+ } else if (input instanceof File) {
+ $image = new Image();
+ src = URL.createObjectURL(input);
+ } else {
+ return Promise.reject("fromImage needs a src, HTMLImageElement or File");
+ }
+ return new Promise(function(resolve, reject) {
+ if (src || !$image.complete) {
+ console.log('Adding eventlistener');
+ $image.addEventListener('load', function() {
+ resolve();
+ }, false);
+ $image.addEventListener('error', function(e) {
+ reject(e);
+ }, false);
+ if (src) {
+ console.log(`Setting src = ${src}`);
+ $image.src = src;
+ }
+ } else {
+ return resolve();
+ }
+ })
+ .then(() => findTagsInObjectURL(src, ['orientation']))
+ .then((tags) => {
+ let width = $image.naturalWidth;
+ let height = $image.naturalHeight;
+ if (tags && tags.orientation) {
+ switch (tags.orientation) {
+ case 6:
+ case 8:
+ width = $image.naturalHeight;
+ height = $image.naturalWidth;
+ }
+ }
+ const imageAR = width / height;
+ const calculatedWidth = imageAR > 1 ? constraints.width : Math.floor((imageAR) * constraints.width);
+ const calculatedHeight = imageAR > 1 ? Math.floor((1 / imageAR) * constraints.width) : constraints.width;
+ const colorChannels = constraints.channels || 3;
+
+ return {
+ type: "IMAGE",
+ colorChannels,
+ tags,
+ getDimensions() {
+ return {
+ viewport: {
+ width: $image.naturalWidth, // AR
+ height: $image.naturalHeight, // AR
+ x: 0, // AR
+ y: 0, // AR
+ },
+ canvas: {
+ width: calculatedWidth, // AR
+ height: calculatedHeight, // AR
+ },
+ };
+ },
+ getDrawable: function() {
+ return $image;
+ },
+ getLabel: function() {
+ return $image.src;
+ },
+ getConstraints: function() {
+ return constraints;
+ },
+ applyConstraints: function() {
+ console.log('ImageSource.applyConstraints not implemented');
+ },
+ };
+ });
+}
diff --git a/src/input/PixelCapture.js b/src/input/PixelCapture.js
index d201bb7..570f298 100644
--- a/src/input/PixelCapture.js
+++ b/src/input/PixelCapture.js
@@ -6,6 +6,8 @@ import {
import {sleep, getViewport} from '../common/utils';
import {aquire} from '../common/buffers';
+const TO_RADIANS = Math.PI / 180;
+
function adjustCanvasSize(input, canvas) {
if (input instanceof HTMLVideoElement) {
if (canvas.height !== input.videoHeight || canvas.width !== input.videoWidth) {
@@ -45,9 +47,8 @@ function drawImage(
canvasSize,
ctx,
source,
- type,
drawable,
- ...drawImageArgs,
+ ...drawImageArgs
) {
let drawAngle = 0;
if (source.type === 'IMAGE') {
@@ -63,10 +64,11 @@ function drawImage(
}
}
+ const [,,,,,, dWidth, dHeight] = drawImageArgs;
if (drawAngle !== 0) {
ctx.translate(canvasSize.width / 2, canvasSize.height / 2);
ctx.rotate(drawAngle);
- ctx.drawImage(drawable, -canvasSize.height / 2, -canvasSize.width / 2, canvasSize.height, canvasSize.width);
+ ctx.drawImage(drawable, -dHeight / 2, -dWidth / 2, dHeight, dWidth);
ctx.rotate(-drawAngle);
ctx.translate(-canvasSize.width / 2, -canvasSize.height / 2);
} else {
diff --git a/src/input/Source.js b/src/input/Source.js
index aaef1e0..ba47887 100644
--- a/src/input/Source.js
+++ b/src/input/Source.js
@@ -3,6 +3,8 @@ import {determineOrientation, PORTRAIT, LANDSCAPE, SQUARE} from '../common/devic
import CameraAccess from './camera_access';
import {getViewport} from '../common/utils';
+export * from './ImageSource';
+
const ConstraintPresets = [
{
width: 720,
@@ -244,77 +246,3 @@ export function fromCanvas(input) {
}
});
}
-
-export function fromImage(input, constraints = {width: 800, height: 800, channels: 3}) {
- var $image = null;
- var src = null;
- if (typeof input === 'string') {
- // data or url, or queryString
- $image = new Image();
- src = input;
- } else if (input instanceof HTMLImageElement) {
- $image = input;
- } else if (input instanceof File) {
- $image = new Image();
- src = URL.createObjectURL(input);
- } else {
- return Promise.reject("fromImage needs a src, HTMLImageElement or File");
- }
- return new Promise(function(resolve, reject) {
- if (src || !$image.complete) {
- console.log('Adding eventlistener');
- $image.addEventListener('load', function() {
- resolve();
- }, false);
- $image.addEventListener('error', function(e) {
- reject(e);
- }, false);
- if (src) {
- console.log(`Setting src = ${src}`);
- $image.src = src;
- }
- } else {
- return resolve();
- }
- })
- .then(() => {
- const width = $image.naturalWidth;
- const height = $image.naturalHeight;
- const imageAR = width / height;
-
- const calculatedWidth = imageAR > 1 ? constraints.width : Math.floor((imageAR) * constraints.width);
- const calculatedHeight = imageAR > 1 ? Math.floor((1 / imageAR) * constraints.width) : constraints.width;
- const colorChannels = constraints.channels || 3;
-
- return {
- type: "IMAGE",
- colorChannels,
- getDimensions() {
- return {
- viewport: {
- width: $image.naturalWidth, // AR
- height: $image.naturalHeight, // AR
- x: 0, // AR
- y: 0, // AR
- },
- canvas: {
- width: calculatedWidth, // AR
- height: calculatedHeight, // AR
- },
- };
- },
- getDrawable: function() {
- return $image;
- },
- getLabel: function() {
- return $image.src;
- },
- getConstraints: function() {
- return constraints;
- },
- applyConstraints: function() {
- console.log('ImageSource.applyConstraints not implemented');
- },
- };
- });
-}
diff --git a/src/scanner.js b/src/scanner.js
index adc1571..2d5174a 100644
--- a/src/scanner.js
+++ b/src/scanner.js
@@ -14,10 +14,10 @@ const vec2 = {
clone: require('gl-vec2/clone')
};
-const getDecoder = memoize((decoderConfig, _inputImageWrapper) => {
- return BarcodeDecoder.create(decoderConfig, _inputImageWrapper);
-}, (decoderConfig, _inputImageWrapper) => {
- return JSON.stringify(Object.assign({}, decoderConfig, {width: _inputImageWrapper.size.x, height: _inputImageWrapper.size.y}));
+const getDecoder = memoize(decoderConfig => {
+ return BarcodeDecoder.create(decoderConfig);
+}, decoderConfig => {
+ return JSON.stringify(decoderConfig);
});
const _checkImageConstraints = memoize((opts) => {
@@ -177,8 +177,8 @@ function createScanner(pixelCapturer) {
boxes = getBoundingBoxes();
if (boxes) {
- result = getDecoder(_config.decoder, _inputImageWrapper)
- .decodeFromBoundingBoxes(boxes);
+ result = getDecoder(_config.decoder)
+ .decodeFromBoundingBoxes(_inputImageWrapper, boxes);
result = result || {};
result.boxes = boxes;
publishResult(result, _inputImageWrapper.data);