mirror of
https://github.com/serratus/quaggaJS.git
synced 2026-08-12 21:21:42 +08:00
Orientation works on iPhone and Android
This commit is contained in:
@@ -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 {
|
||||
|
||||
+2
-74
@@ -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');
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
+6
-6
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user