diff --git a/example/css/styles.css b/example/css/styles.css index 6e5a419..4c7d74b 100644 --- a/example/css/styles.css +++ b/example/css/styles.css @@ -278,10 +278,10 @@ footer { } #interactive.viewport > canvas, #interactive.viewport > video { - max-width: 100%; width: 100%; } canvas.drawing { position: absolute; + z-index: 2; } diff --git a/example/live_w_locator.js b/example/live_w_locator.js index 413e017..8ba5580 100644 --- a/example/live_w_locator.js +++ b/example/live_w_locator.js @@ -170,7 +170,7 @@ $(function() { frequency: 2, decoder: { readers : [{ - format: "ean_reader", + format: "code_128_reader", config: {} }] }, diff --git a/src/input/Source.js b/src/input/Source.js index ba47887..c65ff33 100644 --- a/src/input/Source.js +++ b/src/input/Source.js @@ -78,7 +78,7 @@ function resolveMinWidthToAdvanced({aspectRatio, minPixels}) { .map(({pre}) => pre); } -function getOrCreateVideo(source, target) { +function getOrCreateVideo(target) { const $viewport = getViewport(target); if ($viewport) { let $video = $viewport.querySelector("video"); @@ -153,10 +153,10 @@ function adjustWithZoom(videoConstraints) { }; } -export function fromCamera(constraints) { +export function fromCamera(constraints, {target} = {}) { var {video: videoConstraints, zoom} = adjustWithZoom(constraints); - const video = getOrCreateVideo(); + const video = getOrCreateVideo(target); return CameraAccess.request(video, videoConstraints) .then(function(mediastream) { const track = mediastream.getVideoTracks()[0]; diff --git a/src/quagga.js b/src/quagga.js index 2dcf05c..86cc705 100644 --- a/src/quagga.js +++ b/src/quagga.js @@ -136,7 +136,7 @@ function createApi() { fromCamera(options) { const config = merge({}, Config, options); return Source - .fromCamera(config.constraints) + .fromCamera(config.constraints, {target: config.target}) .then(fromSource.bind(null, config)); }, fromSource(src, inputConfig) { diff --git a/src/scanner.js b/src/scanner.js index f299f79..dd1ca06 100644 --- a/src/scanner.js +++ b/src/scanner.js @@ -7,6 +7,7 @@ import createEventedElement from './common/events'; import {release, aquire, releaseAll} from './common/buffers'; import Config from './config/config'; import CameraAccess from './input/camera_access'; +import {getViewport} from './common/utils'; const vec2 = { clone: require('gl-vec2/clone') @@ -45,17 +46,33 @@ function createScanner(pixelCapturer) { const source = pixelCapturer ? pixelCapturer.getSource() : {}; - function setup() { - let {numOfWorkers} = _config; + function updateViewportStyle(target) { + const $video = source.getDrawable(); + const $viewport = getViewport(target); + + const {viewport} = source.getDimensions(); + const zoom = Math.floor((((2 * viewport.x) + viewport.width) / viewport.width) * 100) / 100; + const videoWidth = zoom * viewport.width; + const translate = ((viewport.x / videoWidth) * (-100)).toFixed(5); + + $video.style.width = `${zoom * 100}%`; + $video.style.transform = `translate(${translate}%, ${translate}%)`; + $viewport.style.paddingBottom = `${(viewport.height * 100 / viewport.width).toFixed(5)}%`; + $viewport.style.overflow = "hidden"; + $viewport.style.height = 0; + } + + function setup({numOfWorkers, target}) { if (source.type === 'IMAGE') { numOfWorkers = numOfWorkers >= 1 ? 1 : 0; } return adjustWorkerPool(numOfWorkers) .then(() => { - if (_config.numOfWorkers === 0) { + if (numOfWorkers === 0) { initBuffers(); } - }); + }) + .then(updateViewportStyle.bind(null, target)); } function initBuffers(imageWrapper) { @@ -92,10 +109,10 @@ function createScanner(pixelCapturer) { } } - function transformResult(result) { - const {viewport} = source.getDimensions(); - let xOffset = viewport.x, - yOffset = viewport.y, + function transformResult(result, dimensions = {}) { + const {clipping = {x: 0, y: 0}} = dimensions; + let xOffset = clipping.x, + yOffset = clipping.y, i; if (xOffset === 0 && yOffset === 0) { @@ -104,7 +121,7 @@ function createScanner(pixelCapturer) { if (result.barcodes) { for (i = 0; i < result.barcodes.length; i++) { - transformResult(result.barcodes[i]); + transformResult(result.barcodes[i], dimensions); } } @@ -158,11 +175,11 @@ function createScanner(pixelCapturer) { result.codeResult); } - function publishResult(result, imageData) { + function publishResult(result, imageData, bitmap) { let resultToPublish = result; if (result && _onUIThread) { - transformResult(result); + transformResult(result, bitmap.dimensions); addResult(result, imageData); resultToPublish = result.barcodes || result; } @@ -173,7 +190,7 @@ function createScanner(pixelCapturer) { } } - function locateAndDecode() { + function locateAndDecode(bitmap) { var result, boxes; @@ -183,9 +200,9 @@ function createScanner(pixelCapturer) { .decodeFromBoundingBoxes(_inputImageWrapper, boxes); result = result || {}; result.boxes = boxes; - publishResult(result, _inputImageWrapper.data); + publishResult(result, _inputImageWrapper.data, bitmap); } else { - publishResult(); + publishResult(undefined, undefined, bitmap); } } @@ -212,10 +229,11 @@ function createScanner(pixelCapturer) { return pixelCapturer.grabFrameData({clipping: calculateClipping}) .then((bitmap) => { if (bitmap) { - console.log(bitmap.dimensions); + //console.log(bitmap.dimensions); // adjust image size! if (availableWorker) { availableWorker.imageData = bitmap.data; + availableWorker.dimensions = bitmap.dimensions; availableWorker.busy = true; availableWorker.worker.postMessage({ cmd: 'process', @@ -223,7 +241,7 @@ function createScanner(pixelCapturer) { }, [availableWorker.imageData.buffer]); } else { _inputImageWrapper.data = bitmap.data; - locateAndDecode(); + locateAndDecode(bitmap); } } }) @@ -286,7 +304,7 @@ function createScanner(pixelCapturer) { } else if (e.data.event === 'processed') { release(e.data.imageData); workerThread.busy = false; - publishResult(e.data.result, workerThread.imageData); + publishResult(e.data.result, workerThread.imageData, workerThread.dimensions); } else if (e.data.event === 'error') { if (ENV.development) { console.log("Worker error: " + e.data.message); @@ -407,7 +425,7 @@ function createScanner(pixelCapturer) { initBuffers(imageWrapper); return cb(); } else { - return setup().then(cb); + return setup(_config).then(cb); } }, start: function() {