Orientation works on iPhone and Android

feature/image-source
Christoph Oberhofer 8 years ago
parent 5f385d490d
commit 41b0d80207

@ -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 {

@ -8,7 +8,7 @@
<meta name="description" content=""/>
<meta name="author" content="Christoph Oberhofer"/>
<meta name="viewport" content="width=device-width; initial-scale=1.0"/>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1"/>
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
</head>

@ -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) {

@ -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');
},
};
});
}

@ -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 {

@ -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');
},
};
});
}

@ -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);

Loading…
Cancel
Save