barcode-detector
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -1,2 +0,2 @@ | ||
function r(r){return r&&"object"==typeof r&&"default"in r?r:{default:r}}var t=r(require("jsqr"));module.exports=function(){function r(r){var t=null==r?void 0:r.formats;if(0===(null==t?void 0:t.length))throw new TypeError("Failed to construct 'BarcodeDetector'");if(null!=t&&t.includes("unknown"))throw new TypeError("Failed to construct 'BarcodeDetector'")}var e=r.prototype;return e.getSupportedFormats=function(){return Promise.resolve(["qr_code"])},e.detect=function(r){try{var e=t.default(r.data,r.width,r.height);if(null!==e){var o=e.data,n=e.location;return Promise.resolve([{boundingBox:DOMRectReadOnly.fromRect({}),rawValue:o,format:"qr_code",cornerPoints:[n.topLeftCorner,n.topRightCorner,n.bottomRightCorner,n.bottomLeftCorner]}])}}catch(r){if(!(r instanceof RangeError))return Promise.reject(r)}},r}(); | ||
function t(e){return(t=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(e)}function e(t,n){return(e=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function r(t,o,i){return(r=n()?Reflect.construct:function(t,n,r){var o=[null];o.push.apply(o,n);var i=new(Function.bind.apply(t,o));return r&&e(i,r.prototype),i}).apply(null,arguments)}function o(n){var i="function"==typeof Map?new Map:void 0;return(o=function(n){if(null===n||-1===Function.toString.call(n).indexOf("[native code]"))return n;if("function"!=typeof n)throw new TypeError("Super expression must either be null or a function");if(void 0!==i){if(i.has(n))return i.get(n);i.set(n,o)}function o(){return r(n,arguments,t(this).constructor)}return o.prototype=Object.create(n.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),e(o,n)})(n)}var i=function(t){var n,r;function o(e){var n;return(n=t.call(this)||this).stringUrl=e,n}return r=t,(n=o).prototype=Object.create(r.prototype),n.prototype.constructor=n,e(n,r),o.prototype.postMessage=function(t,e){var n=this;void 0===this.worker?(this.worker=new Worker(this.stringUrl),this.worker.onmessage=function(t){n.dispatchEvent(new MessageEvent("message",{data:t.data}))}):self.clearTimeout(this.timeout),this.worker.postMessage(t,e),this.timeout=self.setTimeout(function(){n.worker.terminate(),n.worker=void 0},1e3)},o}(o(EventTarget));function a(t,e,n){var r=document.createElement("canvas"),o=r.getContext("2d");return r.width=e,r.height=n,o.drawImage(t,0,0,e,n),o.getImageData(0,0,e,n)}module.exports=function(){function t(t){var e;this.worker=(e=function(){self.importScripts("https://cdn.jsdelivr.net/npm/jsqr@1.3.1/dist/jsQR.min.js"),self.addEventListener("message",function(t){var e=t.data;try{var n=self.jsQR(e.data,e.width,e.height,{inversionAttempts:"dontInvert"});self.postMessage(n)}catch(t){if(!(t instanceof RangeError))throw t}})}.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1],new i(URL.createObjectURL(new Blob([e],{type:"text/javascript"})))),this.workerBusy=!1}var e=t.prototype;return e.getSupportedFormats=function(){return Promise.resolve(["qr_code"])},e.detect=function(t){try{var e=this;return Promise.resolve(function(){if(e.workerBusy)return[];e.workerBusy=!0;var n=function(t){if(t instanceof HTMLImageElement)return a(t,t.naturalWidth,t.naturalHeight);if(t instanceof SVGImageElement)return a(t,640,480);if(t instanceof HTMLVideoElement){if(0===t.readyState||1===t.readyState)throw new DOMException("","InvalidStateError");return a(t,t.videoWidth,t.videoHeight)}return t instanceof HTMLCanvasElement?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof ImageBitmap?a(t,t.width,t.height):t instanceof OffscreenCanvas?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof Blob?void 0:t instanceof ImageData?t:void 0}(t);return e.worker.postMessage(n,[n.data.buffer]),function(t,n){try{var r=function(t,n){try{var r=Promise.resolve(new Promise(function(t){e.worker.addEventListener("message",function(e){t(e.data)})})).then(function(t){if(null===t)return[];var e=Object.freeze([t.location.topLeftCorner,t.location.topRightCorner,t.location.bottomRightCorner,t.location.bottomLeftCorner]),n=Math.min.apply(Math,e.map(function(t){return t.x})),r=Math.max.apply(Math,e.map(function(t){return t.x})),o=Math.min.apply(Math,e.map(function(t){return t.y})),i=Math.max.apply(Math,e.map(function(t){return t.y}));return[{boundingBox:DOMRectReadOnly.fromRect({x:n,y:o,width:r-n,height:i-o}),rawValue:t.data,format:"qr_code",cornerPoints:e}]})}catch(t){return[]}return r&&r.then?r.then(void 0,function(){return[]}):r}()}catch(t){return n(!0,t)}return r&&r.then?r.then(n.bind(null,!1),n.bind(null,!0)):n(!1,r)}(0,function(t,n){if(e.workerBusy=!1,t)throw n;return n})}())}catch(t){return Promise.reject(t)}},t}(); | ||
//# sourceMappingURL=barcode-detector.js.map |
@@ -1,2 +0,2 @@ | ||
import r from"jsqr";export default class{constructor(r){const o=null==r?void 0:r.formats;if(0===(null==o?void 0:o.length))throw new TypeError("Failed to construct 'BarcodeDetector'");if(null!=o&&o.includes("unknown"))throw new TypeError("Failed to construct 'BarcodeDetector'")}getSupportedFormats(){return Promise.resolve(["qr_code"])}detect(o){try{const t=r(o.data,o.width,o.height);if(null!==t){const{data:r,location:o}=t;return Promise.resolve([{boundingBox:DOMRectReadOnly.fromRect({}),rawValue:r,format:"qr_code",cornerPoints:[o.topLeftCorner,o.topRightCorner,o.bottomRightCorner,o.bottomLeftCorner]}])}}catch(r){if(!(r instanceof RangeError))return Promise.reject(r)}}} | ||
class t extends EventTarget{constructor(t){super(),this.stringUrl=t}postMessage(t,e){void 0===this.worker?(this.worker=new Worker(this.stringUrl),this.worker.onmessage=t=>{this.dispatchEvent(new MessageEvent("message",{data:t.data}))}):self.clearTimeout(this.timeout),this.worker.postMessage(t,e),this.timeout=self.setTimeout(()=>{this.worker.terminate(),this.worker=void 0},1e3)}}function e(t,e,r){const n=document.createElement("canvas"),a=n.getContext("2d");return n.width=e,n.height=r,a.drawImage(t,0,0,e,r),a.getImageData(0,0,e,r)}export default class{constructor(e){this.worker=(e=>{const r=function(){self.importScripts("https://cdn.jsdelivr.net/npm/jsqr@1.3.1/dist/jsQR.min.js"),self.addEventListener("message",function(t){const e=t.data;try{const t=self.jsQR(e.data,e.width,e.height,{inversionAttempts:"dontInvert"});self.postMessage(t)}catch(t){if(!(t instanceof RangeError))throw t}})}.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1];return new t(URL.createObjectURL(new Blob([r],{type:"text/javascript"})))})(),this.workerBusy=!1}getSupportedFormats(){return Promise.resolve(["qr_code"])}async detect(t){if(this.workerBusy)return[];{this.workerBusy=!0;const r=function(t){if(t instanceof HTMLImageElement)return e(t,t.naturalWidth,t.naturalHeight);if(t instanceof SVGImageElement)return e(t,640,480);if(t instanceof HTMLVideoElement){const r=1;if(0===t.readyState||t.readyState===r)throw new DOMException("","InvalidStateError");return e(t,t.videoWidth,t.videoHeight)}return t instanceof HTMLCanvasElement?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof ImageBitmap?e(t,t.width,t.height):t instanceof OffscreenCanvas?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof Blob?void 0:t instanceof ImageData?t:void 0}(t);this.worker.postMessage(r,[r.data.buffer]);try{const t=await new Promise(t=>{this.worker.addEventListener("message",e=>{t(e.data)})});if(null===t)return[];{const e=Object.freeze([t.location.topLeftCorner,t.location.topRightCorner,t.location.bottomRightCorner,t.location.bottomLeftCorner]),r=Math.min(...e.map(t=>t.x)),n=Math.max(...e.map(t=>t.x)),a=Math.min(...e.map(t=>t.y)),s=Math.max(...e.map(t=>t.y));return[{boundingBox:DOMRectReadOnly.fromRect({x:r,y:a,width:n-r,height:s-a}),rawValue:t.data,format:"qr_code",cornerPoints:e}]}}catch(t){return[]}finally{this.workerBusy=!1}}}} | ||
//# sourceMappingURL=barcode-detector.modern.js.map |
@@ -1,2 +0,2 @@ | ||
import r from"jsqr";var t=function(){function t(r){var t=null==r?void 0:r.formats;if(0===(null==t?void 0:t.length))throw new TypeError("Failed to construct 'BarcodeDetector'");if(null!=t&&t.includes("unknown"))throw new TypeError("Failed to construct 'BarcodeDetector'")}var o=t.prototype;return o.getSupportedFormats=function(){return Promise.resolve(["qr_code"])},o.detect=function(t){try{var o=r(t.data,t.width,t.height);if(null!==o){var e=o.data,n=o.location;return Promise.resolve([{boundingBox:DOMRectReadOnly.fromRect({}),rawValue:e,format:"qr_code",cornerPoints:[n.topLeftCorner,n.topRightCorner,n.bottomRightCorner,n.bottomLeftCorner]}])}}catch(r){if(!(r instanceof RangeError))return Promise.reject(r)}},t}();export default t; | ||
function t(e){return(t=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(e)}function e(t,n){return(e=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function r(t,o,i){return(r=n()?Reflect.construct:function(t,n,r){var o=[null];o.push.apply(o,n);var i=new(Function.bind.apply(t,o));return r&&e(i,r.prototype),i}).apply(null,arguments)}function o(n){var i="function"==typeof Map?new Map:void 0;return(o=function(n){if(null===n||-1===Function.toString.call(n).indexOf("[native code]"))return n;if("function"!=typeof n)throw new TypeError("Super expression must either be null or a function");if(void 0!==i){if(i.has(n))return i.get(n);i.set(n,o)}function o(){return r(n,arguments,t(this).constructor)}return o.prototype=Object.create(n.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),e(o,n)})(n)}var i=function(t){var n,r;function o(e){var n;return(n=t.call(this)||this).stringUrl=e,n}return r=t,(n=o).prototype=Object.create(r.prototype),n.prototype.constructor=n,e(n,r),o.prototype.postMessage=function(t,e){var n=this;void 0===this.worker?(this.worker=new Worker(this.stringUrl),this.worker.onmessage=function(t){n.dispatchEvent(new MessageEvent("message",{data:t.data}))}):self.clearTimeout(this.timeout),this.worker.postMessage(t,e),this.timeout=self.setTimeout(function(){n.worker.terminate(),n.worker=void 0},1e3)},o}(o(EventTarget));function a(t,e,n){var r=document.createElement("canvas"),o=r.getContext("2d");return r.width=e,r.height=n,o.drawImage(t,0,0,e,n),o.getImageData(0,0,e,n)}var u=function(){function t(t){var e;this.worker=(e=function(){self.importScripts("https://cdn.jsdelivr.net/npm/jsqr@1.3.1/dist/jsQR.min.js"),self.addEventListener("message",function(t){var e=t.data;try{var n=self.jsQR(e.data,e.width,e.height,{inversionAttempts:"dontInvert"});self.postMessage(n)}catch(t){if(!(t instanceof RangeError))throw t}})}.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1],new i(URL.createObjectURL(new Blob([e],{type:"text/javascript"})))),this.workerBusy=!1}var e=t.prototype;return e.getSupportedFormats=function(){return Promise.resolve(["qr_code"])},e.detect=function(t){try{var e=this;return Promise.resolve(function(){if(e.workerBusy)return[];e.workerBusy=!0;var n=function(t){if(t instanceof HTMLImageElement)return a(t,t.naturalWidth,t.naturalHeight);if(t instanceof SVGImageElement)return a(t,640,480);if(t instanceof HTMLVideoElement){if(0===t.readyState||1===t.readyState)throw new DOMException("","InvalidStateError");return a(t,t.videoWidth,t.videoHeight)}return t instanceof HTMLCanvasElement?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof ImageBitmap?a(t,t.width,t.height):t instanceof OffscreenCanvas?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof Blob?void 0:t instanceof ImageData?t:void 0}(t);return e.worker.postMessage(n,[n.data.buffer]),function(t,n){try{var r=function(t,n){try{var r=Promise.resolve(new Promise(function(t){e.worker.addEventListener("message",function(e){t(e.data)})})).then(function(t){if(null===t)return[];var e=Object.freeze([t.location.topLeftCorner,t.location.topRightCorner,t.location.bottomRightCorner,t.location.bottomLeftCorner]),n=Math.min.apply(Math,e.map(function(t){return t.x})),r=Math.max.apply(Math,e.map(function(t){return t.x})),o=Math.min.apply(Math,e.map(function(t){return t.y})),i=Math.max.apply(Math,e.map(function(t){return t.y}));return[{boundingBox:DOMRectReadOnly.fromRect({x:n,y:o,width:r-n,height:i-o}),rawValue:t.data,format:"qr_code",cornerPoints:e}]})}catch(t){return[]}return r&&r.then?r.then(void 0,function(){return[]}):r}()}catch(t){return n(!0,t)}return r&&r.then?r.then(n.bind(null,!1),n.bind(null,!0)):n(!1,r)}(0,function(t,n){if(e.workerBusy=!1,t)throw n;return n})}())}catch(t){return Promise.reject(t)}},t}();export default u; | ||
//# sourceMappingURL=barcode-detector.module.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("jsqr")):"function"==typeof define&&define.amd?define(["jsqr"],t):(e||self).barcodeDetector=t(e.jsqr)}(this,function(e){function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=t(e);return function(){function e(e){var t=null==e?void 0:e.formats;if(0===(null==t?void 0:t.length))throw new TypeError("Failed to construct 'BarcodeDetector'");if(null!=t&&t.includes("unknown"))throw new TypeError("Failed to construct 'BarcodeDetector'")}var t=e.prototype;return t.getSupportedFormats=function(){return Promise.resolve(["qr_code"])},t.detect=function(e){try{var t=o.default(e.data,e.width,e.height);if(null!==t){var r=t.data,n=t.location;return Promise.resolve([{boundingBox:DOMRectReadOnly.fromRect({}),rawValue:r,format:"qr_code",cornerPoints:[n.topLeftCorner,n.topRightCorner,n.bottomRightCorner,n.bottomLeftCorner]}])}}catch(e){if(!(e instanceof RangeError))return Promise.reject(e)}},e}()}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t||self).barcodeDetector=e()}(this,function(){function t(e){return(t=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(e)}function e(t,n){return(e=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function r(t,o,i){return(r=n()?Reflect.construct:function(t,n,r){var o=[null];o.push.apply(o,n);var i=new(Function.bind.apply(t,o));return r&&e(i,r.prototype),i}).apply(null,arguments)}function o(n){var i="function"==typeof Map?new Map:void 0;return(o=function(n){if(null===n||-1===Function.toString.call(n).indexOf("[native code]"))return n;if("function"!=typeof n)throw new TypeError("Super expression must either be null or a function");if(void 0!==i){if(i.has(n))return i.get(n);i.set(n,o)}function o(){return r(n,arguments,t(this).constructor)}return o.prototype=Object.create(n.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),e(o,n)})(n)}var i=function(t){var n,r;function o(e){var n;return(n=t.call(this)||this).stringUrl=e,n}return r=t,(n=o).prototype=Object.create(r.prototype),n.prototype.constructor=n,e(n,r),o.prototype.postMessage=function(t,e){var n=this;void 0===this.worker?(this.worker=new Worker(this.stringUrl),this.worker.onmessage=function(t){n.dispatchEvent(new MessageEvent("message",{data:t.data}))}):self.clearTimeout(this.timeout),this.worker.postMessage(t,e),this.timeout=self.setTimeout(function(){n.worker.terminate(),n.worker=void 0},1e3)},o}(o(EventTarget));function a(t,e,n){var r=document.createElement("canvas"),o=r.getContext("2d");return r.width=e,r.height=n,o.drawImage(t,0,0,e,n),o.getImageData(0,0,e,n)}return function(){function t(t){var e;this.worker=(e=function(){self.importScripts("https://cdn.jsdelivr.net/npm/jsqr@1.3.1/dist/jsQR.min.js"),self.addEventListener("message",function(t){var e=t.data;try{var n=self.jsQR(e.data,e.width,e.height,{inversionAttempts:"dontInvert"});self.postMessage(n)}catch(t){if(!(t instanceof RangeError))throw t}})}.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1],new i(URL.createObjectURL(new Blob([e],{type:"text/javascript"})))),this.workerBusy=!1}var e=t.prototype;return e.getSupportedFormats=function(){return Promise.resolve(["qr_code"])},e.detect=function(t){try{var e=this;return Promise.resolve(function(){if(e.workerBusy)return[];e.workerBusy=!0;var n=function(t){if(t instanceof HTMLImageElement)return a(t,t.naturalWidth,t.naturalHeight);if(t instanceof SVGImageElement)return a(t,640,480);if(t instanceof HTMLVideoElement){if(0===t.readyState||1===t.readyState)throw new DOMException("","InvalidStateError");return a(t,t.videoWidth,t.videoHeight)}return t instanceof HTMLCanvasElement?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof ImageBitmap?a(t,t.width,t.height):t instanceof OffscreenCanvas?t.getContext("2d").getImageData(0,0,t.width,t.height):t instanceof Blob?void 0:t instanceof ImageData?t:void 0}(t);return e.worker.postMessage(n,[n.data.buffer]),function(t,n){try{var r=function(t,n){try{var r=Promise.resolve(new Promise(function(t){e.worker.addEventListener("message",function(e){t(e.data)})})).then(function(t){if(null===t)return[];var e=Object.freeze([t.location.topLeftCorner,t.location.topRightCorner,t.location.bottomRightCorner,t.location.bottomLeftCorner]),n=Math.min.apply(Math,e.map(function(t){return t.x})),r=Math.max.apply(Math,e.map(function(t){return t.x})),o=Math.min.apply(Math,e.map(function(t){return t.y})),i=Math.max.apply(Math,e.map(function(t){return t.y}));return[{boundingBox:DOMRectReadOnly.fromRect({x:n,y:o,width:r-n,height:i-o}),rawValue:t.data,format:"qr_code",cornerPoints:e}]})}catch(t){return[]}return r&&r.then?r.then(void 0,function(){return[]}):r}()}catch(t){return n(!0,t)}return r&&r.then?r.then(n.bind(null,!1),n.bind(null,!0)):n(!1,r)}(0,function(t,n){if(e.workerBusy=!1,t)throw n;return n})}())}catch(t){return Promise.reject(t)}},t}()}); | ||
//# sourceMappingURL=barcode-detector.umd.js.map |
@@ -1,4 +0,7 @@ | ||
declare type BarcodeFormat = "aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "data_matrix" | "ean_13" | "ean_8" | "itf" | "pdf417" | "qr_code" | "unknown" | "upc_a" | "upc_e"; | ||
import SleepyWorker from "./SleepyWorker"; | ||
declare type BarcodeFormatIn = "aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "data_matrix" | "ean_13" | "ean_8" | "itf" | "pdf417" | "qr_code" | "upc_a" | "upc_e"; | ||
declare type BarcodeFormatOut = BarcodeFormatIn | "unknown"; | ||
declare type NonEmptyArray<T> = [T, ...T[]]; | ||
interface BarcodeDetectorOptions { | ||
formats?: Array<BarcodeFormat>; | ||
formats?: NonEmptyArray<BarcodeFormatIn>; | ||
} | ||
@@ -10,12 +13,14 @@ interface Point2D { | ||
interface DetectedBarcode { | ||
boundingBox: any; | ||
boundingBox: DOMRectReadOnly; | ||
rawValue: String; | ||
format: BarcodeFormat; | ||
cornerPoints: Array<Point2D>; | ||
format: BarcodeFormatOut; | ||
cornerPoints: ReadonlyArray<Point2D>; | ||
} | ||
export default class BarcodeDetector { | ||
worker: SleepyWorker; | ||
workerBusy: boolean; | ||
constructor(barcodeDetectorOptions?: BarcodeDetectorOptions); | ||
getSupportedFormats(): Promise<Array<BarcodeFormat>>; | ||
detect(image: ImageData): Promise<Array<DetectedBarcode>>; | ||
getSupportedFormats(): Promise<Array<BarcodeFormatOut>>; | ||
detect(image: ImageBitmapSource): Promise<Array<DetectedBarcode>>; | ||
} | ||
export {}; |
{ | ||
"name": "barcode-detector", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "", | ||
"source": "src/BarcodeDetector.ts", | ||
"main": "dist/barcode-detector.js", | ||
"exports": "./dist/barcode-detector.modern.js", | ||
"module": "dist/barcode-detector.module.js", | ||
"exports": "./dist/barcode-detector.modern.js", | ||
"module": "dist/barcode-detector.module.js", | ||
"unpkg": "dist/barcode-detector.umd.js", | ||
"scripts": { | ||
"build": "microbundle", | ||
"dev": "microbundle watch" | ||
"dev": "microbundle watch" | ||
}, | ||
@@ -14,0 +14,0 @@ "author": "Niklas Gruhn", |
@@ -1,1 +0,41 @@ | ||
# barcode-detector | ||
# `BarcodeDetector` Polyfill | ||
Spec compliant polyfill of the [Barcode Detection API](https://wicg.github.io/shape-detection-api/#barcode-detection-api). | ||
It can be used for barcode/QR-code recognition in images from various kinds of | ||
sources including `<canvas>`, `<img>`, `<video>`, `Blob`, `ImageData`, ... | ||
[TODO: live demos] | ||
## Installation | ||
```sh | ||
npm install barcode-detector | ||
``` | ||
```js | ||
import BarcodeDetector from "barcode-detector" | ||
// polyfill unless already supported | ||
if (!("BarcodeDetector" in window)) { | ||
window.BarcodeDetector = BarcodeDetector | ||
} | ||
``` | ||
## Usage | ||
For in-depth documentation checkout the [corresponding MDN page](https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API). | ||
### Supported Formats | ||
- :x: `aztec` | ||
- :x: `code_128` | ||
- :x: `code_39` | ||
- :x: `code_93` | ||
- :x: `codabar` | ||
- :x: `data_matrix` | ||
- :x: `ean_13` | ||
- :x: `ean_8` | ||
- :x: `itf` | ||
- :x: `pdf417` | ||
- :heavy_check_mark: `qr_code` | ||
- :x: `upc_a` | ||
- :x: `upc_e` |
// spec: https://wicg.github.io/shape-detection-api/#barcode-detection-api | ||
import jsQR from "jsqr" | ||
import DetectWorker from "./DetectWorker" | ||
import SleepyWorker from "./SleepyWorker" | ||
import { imageDataFrom } from "./image-data" | ||
type BarcodeFormat | ||
type BarcodeFormatIn | ||
= "aztec" | ||
@@ -18,15 +19,21 @@ | "code_128" | ||
| "qr_code" | ||
| "unknown" | ||
| "upc_a" | ||
| "upc_e" | ||
type BarcodeFormatOut | ||
= BarcodeFormatIn | ||
| "unknown" | ||
type NonEmptyArray<T> | ||
= [T, ...T[]] | ||
interface BarcodeDetectorOptions { | ||
// A series of BarcodeFormats to search for in the subsequent detect() calls. | ||
// If not present then the UA SHOULD search for all supported formats. | ||
formats? : Array<BarcodeFormat> | ||
formats? : NonEmptyArray<BarcodeFormatIn> | ||
}; | ||
interface Point2D { | ||
x : Number, // default: 0.0 | ||
y : Number // default: 0.0 | ||
x : Number, | ||
y : Number | ||
}; | ||
@@ -37,4 +44,4 @@ | ||
rawValue : String, | ||
format : BarcodeFormat, | ||
cornerPoints : Array<Point2D> // should be frozen | ||
format : BarcodeFormatOut, | ||
cornerPoints : ReadonlyArray<Point2D> | ||
}; | ||
@@ -44,21 +51,11 @@ | ||
worker : SleepyWorker | ||
workerBusy : boolean | ||
constructor (barcodeDetectorOptions? : BarcodeDetectorOptions) { | ||
const formats = barcodeDetectorOptions?.formats | ||
if (formats !== undefined) { | ||
// If barcodeDetectorOptions.formats is present and empty, then throw a new TypeError. | ||
if (formats.length === 0) { | ||
throw new TypeError("Failed to construct 'BarcodeDetector'") | ||
} | ||
// If barcodeDetectorOptions.formats is present and contains unknown, then throw a new TypeError. | ||
if (formats.includes("unknown")) { | ||
throw new TypeError("Failed to construct 'BarcodeDetector'") | ||
} | ||
} | ||
this.worker = DetectWorker() | ||
this.workerBusy = false | ||
} | ||
getSupportedFormats() : Promise<Array<BarcodeFormat>> { | ||
getSupportedFormats() : Promise<Array<BarcodeFormatOut>> { | ||
return Promise.resolve([ | ||
@@ -76,34 +73,59 @@ // "code_128", | ||
// TODO actually input type is ImageBitmapSource | ||
detect(image : ImageData) : Promise<Array<DetectedBarcode>> { | ||
// TODO reject promise under various situations: | ||
// https://wicg.github.io/shape-detection-api/#image-sources-for-detection | ||
async detect(image : ImageBitmapSource) : Promise<Array<DetectedBarcode>> { | ||
// [TODO] | ||
// Note that if the ImageBitmapSource is an object with either a horizontal | ||
// dimension or a vertical dimension equal to zero, then the Promise will | ||
// be simply resolved with an empty sequence of detected objects. | ||
try { | ||
const result = jsQR(image.data, image.width, image.height); | ||
// If worker can't process frames fast enough, memory quickly fills up. | ||
// Make sure to process only one frame at a time. | ||
if (this.workerBusy) { | ||
return [] | ||
} else { | ||
this.workerBusy = true | ||
if (result === null) { | ||
const imageData = imageDataFrom(image) | ||
this.worker.postMessage(imageData, [imageData.data.buffer]) | ||
} else { | ||
const { data, location } = result | ||
try { | ||
const result : any = await new Promise(resolve => { | ||
this.worker.addEventListener("message", (event : any) => { | ||
resolve(event.data) | ||
}); | ||
}) | ||
return Promise.resolve([{ | ||
boundingBox: DOMRectReadOnly.fromRect({}), // TODO | ||
rawValue: data, | ||
format: "qr_code", | ||
cornerPoints: [ | ||
location.topLeftCorner, | ||
location.topRightCorner, | ||
location.bottomRightCorner, | ||
location.bottomLeftCorner | ||
] | ||
}]) | ||
if (result === null) { | ||
return [] | ||
} else { | ||
const cornerPoints = Object.freeze([ | ||
result.location.topLeftCorner, | ||
result.location.topRightCorner, | ||
result.location.bottomRightCorner, | ||
result.location.bottomLeftCorner | ||
]) | ||
const x1 = Math.min(...cornerPoints.map(point => point.x)) | ||
const x2 = Math.max(...cornerPoints.map(point => point.x)) | ||
const y1 = Math.min(...cornerPoints.map(point => point.y)) | ||
const y2 = Math.max(...cornerPoints.map(point => point.y)) | ||
return [{ | ||
boundingBox: DOMRectReadOnly.fromRect({ // TODO is this correct? | ||
x: x1, | ||
y: y1, | ||
width: x2 - x1, | ||
height: y2 - y1 | ||
}), | ||
rawValue: result.data, | ||
format: "qr_code", | ||
cornerPoints | ||
}] | ||
} | ||
} catch (error) { | ||
return [] | ||
} finally { | ||
this.workerBusy = false; | ||
} | ||
} catch (error) { | ||
if (!(error instanceof RangeError)) { | ||
return Promise.reject(error); | ||
} | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances in 1 package
81600
19
343
2
41
1