├── README.md
└── examples
├── 9.x
├── barcode-reader.html
├── barcode-result-overlay.html
├── dbr-scanner-wrapper.js
├── dbr-scanner-wrapper.ts
├── driver_license
│ ├── README.md
│ ├── driverlicense.js
│ └── index.html
├── hello-world.html
├── manually-load.html
├── overlay.js
├── pwa
│ ├── README.md
│ ├── favicon.ico
│ ├── icons
│ │ ├── icon-128.png
│ │ ├── icon-144.png
│ │ ├── icon-152.png
│ │ ├── icon-192.png
│ │ ├── icon-256.png
│ │ └── icon-32.png
│ ├── index.html
│ ├── manifest.json
│ ├── overlay.js
│ ├── service-worker.js
│ └── style.css
├── qr-code-scanner.html
├── salesforce_visualforce_page
│ ├── .eslintignore
│ ├── .forceignore
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc
│ ├── .vscode
│ │ ├── extensions.json
│ │ ├── launch.json
│ │ └── settings.json
│ ├── README.md
│ ├── config
│ │ └── project-scratch-def.json
│ ├── force-app
│ │ └── main
│ │ │ └── default
│ │ │ ├── aura
│ │ │ └── .eslintrc.json
│ │ │ ├── lwc
│ │ │ └── .eslintrc.json
│ │ │ └── pages
│ │ │ ├── DecodeFile.html
│ │ │ ├── DecodeFile.page
│ │ │ ├── DecodeFile.page-meta.xml
│ │ │ ├── DecodeVideo.html
│ │ │ ├── DecodeVideo.page
│ │ │ └── DecodeVideo.page-meta.xml
│ ├── package.json
│ ├── scripts
│ │ ├── apex
│ │ │ └── hello.apex
│ │ └── soql
│ │ │ └── account.soql
│ └── sfdx-project.json
├── ui-customization.html
├── webgl
│ ├── README.md
│ ├── grayscale-image
│ │ ├── 640x480.jpg
│ │ └── index.html
│ ├── index.html
│ ├── loading.gif
│ ├── m4.js
│ ├── util.js
│ └── webgl-utils.js
└── wrapper-test.html
├── aadhaar_card
└── index.html
├── barcode_mrz_document
├── README.md
├── default.png
├── full.json
├── index.html
├── main.js
├── styles.css
└── utils.js
├── barcode_ocr_text
├── index.html
├── main.css
├── main.js
└── template.json
├── camera_only
├── README.md
└── index.html
├── mrz-vin-scanner
├── README.md
├── default.png
├── full.json
├── index.html
├── main.js
├── mrz.json
├── styles.css
└── vin.json
└── mrz_scanner_rtu
├── README.md
├── helloworld.html
├── index.html
└── main.css
/README.md:
--------------------------------------------------------------------------------
1 | # Scan 1D/2D Barcode, MRZ and Documents in JavaScript
2 | This repository contains **JavaScript** examples demonstrating how to use [Dynamsoft Capture Vision](https://www.npmjs.com/package/dynamsoft-capture-vision-bundle) to build web applications for scanning **1D/2D barcodes**, **MRZ**, and **documents**.
3 |
4 | ## Prerequisites
5 | - Obtain a [30-day trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform).
6 |
7 | ## Try Examples
8 | - [barcode-reader.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/barcode-reader.html)
9 | - [barcode-result-overlay.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/barcode-result-overlay.html)
10 | - [hello-world.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/hello-world.html)
11 | - [manually-load.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/manually-load.html)
12 | - [qr-code-scanner.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/qr-code-scanner.html)
13 | - [ui-customization.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/ui-customization.html)
14 | - [wrapper-test.html](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/wrapper-test.html)
15 |
16 | Build the TypeScript file:
17 |
18 | ```bash
19 | tsc --target ES5 dbr-scanner-wrapper.ts
20 | ```
21 |
22 | - [WebGL](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/webgl/)
23 | - [Driver License PDF417 Scanner](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/driver_license/)
24 | - [Scan 1D Barcode and OCR Text](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/barcode_ocr_text)
25 | - [Detect Barcode, MRZ and Document](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/barcode_mrz_document/)
26 | - [Aadhaar Card](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/aadhaar_card/)
27 |
28 | ## Blog
29 | - [How to Use WebGL to Accelerate Web Barcode and QR Code Decoding Speed](https://www.dynamsoft.com/codepool/webgl-accelerate-web-barcode-decoding-speed.html)
30 | - [Build a Barcode Scanner Using JavaScript and HTML5](https://www.dynamsoft.com/codepool/html5-barcode-reader-javascript-webassembly.html)
31 | - [Reading Driver’s License Information from PDF417 in JavaScript](https://www.dynamsoft.com/codepool/javascript-driver-license-pdf417-web.html)
32 |
--------------------------------------------------------------------------------
/examples/9.x/barcode-reader.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Reader
8 |
9 |
10 |
67 |
68 |
69 |
70 |
83 |
84 |
Image Panel
85 |
Loading Library...
86 |
87 |
88 |
89 |
92 |
93 |
94 |

95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
187 |
188 |
189 |
--------------------------------------------------------------------------------
/examples/9.x/barcode-result-overlay.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Scanner
8 |
9 |
10 |
47 |
48 |
49 |
50 |
51 | Barcode Result:
N/A
52 |
53 |
54 | Loading Library...
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
66 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/examples/9.x/dbr-scanner-wrapper.js:
--------------------------------------------------------------------------------
1 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3 | return new (P || (P = Promise))(function (resolve, reject) {
4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7 | step((generator = generator.apply(thisArg, _arguments || [])).next());
8 | });
9 | };
10 | var __generator = (this && this.__generator) || function (thisArg, body) {
11 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13 | function verb(n) { return function (v) { return step([n, v]); }; }
14 | function step(op) {
15 | if (f) throw new TypeError("Generator is already executing.");
16 | while (_) try {
17 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18 | if (y = 0, t) op = [op[0] & 2, t.value];
19 | switch (op[0]) {
20 | case 0: case 1: t = op; break;
21 | case 4: _.label++; return { value: op[1], done: false };
22 | case 5: _.label++; y = op[1]; op = [0]; continue;
23 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
24 | default:
25 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29 | if (t[2]) _.ops.pop();
30 | _.trys.pop(); continue;
31 | }
32 | op = body.call(thisArg, _);
33 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35 | }
36 | };
37 | var DBRWrapper = /** @class */ (function () {
38 | function DBRWrapper() {
39 | try {
40 | this.scanner = null;
41 | this.videoContainer = null;
42 | this.cameraSourceElement = null;
43 | this.cameraViewElement = null;
44 | this.overlay = null;
45 | this.context = null;
46 | this.selectElement = null;
47 | this.cameraInfo = {};
48 | this.openCamera = this.openCamera.bind(this);
49 | this.onCameraReady = this.onCameraReady.bind(this);
50 | }
51 | catch (ex) {
52 | alert(ex.message);
53 | throw ex;
54 | }
55 | }
56 | DBRWrapper.createInstance = function () {
57 | return new DBRWrapper();
58 | };
59 | DBRWrapper.prototype.createCustomScanner = function (callback) {
60 | return __awaiter(this, void 0, void 0, function () {
61 | var _a, cameras;
62 | var _this = this;
63 | return __generator(this, function (_b) {
64 | switch (_b.label) {
65 | case 0:
66 | this.initCameraSource();
67 | this.initCameraView();
68 | return [4 /*yield*/, Dynamsoft.DBR.BarcodeScanner.loadWasm()];
69 | case 1:
70 | _b.sent();
71 | _a = this;
72 | return [4 /*yield*/, Dynamsoft.DBR.BarcodeScanner.createInstance()];
73 | case 2:
74 | _a.scanner = _b.sent();
75 | return [4 /*yield*/, this.scanner.updateRuntimeSettings("speed")];
76 | case 3:
77 | _b.sent();
78 | return [4 /*yield*/, this.scanner.setUIElement(this.videoContainer)];
79 | case 4:
80 | _b.sent();
81 | return [4 /*yield*/, this.scanner.getAllCameras()];
82 | case 5:
83 | cameras = _b.sent();
84 | this.appendCameraSource(cameras);
85 | return [4 /*yield*/, this.openCamera()];
86 | case 6:
87 | _b.sent();
88 | this.scanner.onFrameRead = function (results) {
89 | _this.clearOverlay();
90 | var txts = [];
91 | var localization;
92 | if (results.length > 0) {
93 | for (var i = 0; i < results.length; ++i) {
94 | txts.push(results[i].barcodeText);
95 | localization = results[i].localizationResult;
96 | _this.drawOverlay(localization, results[i].barcodeText);
97 | }
98 | if (callback) {
99 | callback(txts.join(', '));
100 | }
101 | }
102 | else {
103 | if (callback) {
104 | callback("No barcode found");
105 | }
106 | }
107 | };
108 | this.scanner.onUnduplicatedRead = function (txt, result) { };
109 | this.scanner.onPlayed = this.onCameraReady;
110 | return [2 /*return*/, this.scanner];
111 | }
112 | });
113 | });
114 | };
115 | DBRWrapper.prototype.createDefaultScanner = function (callback) {
116 | return __awaiter(this, void 0, void 0, function () {
117 | var _a;
118 | var _this = this;
119 | return __generator(this, function (_b) {
120 | switch (_b.label) {
121 | case 0:
122 | _a = this;
123 | return [4 /*yield*/, Dynamsoft.DBR.BarcodeScanner.createInstance()];
124 | case 1:
125 | _a.scanner = _b.sent();
126 | return [4 /*yield*/, this.scanner.updateRuntimeSettings("speed")];
127 | case 2:
128 | _b.sent();
129 | this.scanner.onFrameRead = function (results) {
130 | _this.clearOverlay();
131 | var txts = [];
132 | var localization;
133 | if (results.length > 0) {
134 | for (var i = 0; i < results.length; ++i) {
135 | txts.push(results[i].barcodeText);
136 | localization = results[i].localizationResult;
137 | _this.drawOverlay(localization, results[i].barcodeText);
138 | }
139 | }
140 | if (callback) {
141 | callback(results);
142 | }
143 | };
144 | this.scanner.onUnduplicatedRead = function (txt, result) { };
145 | this.scanner.onPlayed = this.onCameraReady;
146 | return [2 /*return*/, this.scanner];
147 | }
148 | });
149 | });
150 | };
151 | DBRWrapper.prototype.patchOverlay = function () {
152 | var containers = document.getElementsByClassName("dce-video-container");
153 | if (containers == null || containers.length == 0) {
154 | return;
155 | }
156 | // Always select last element.
157 | var container = document.getElementsByClassName("dce-video-container")[containers.length - 1];
158 | var lastElement = container.lastElementChild;
159 | if (lastElement && lastElement.id === "custom-overlay")
160 | container.removeChild(lastElement);
161 | this.overlay = document.createElement('canvas');
162 | this.overlay.id = "custom-overlay";
163 | this.overlay.style.position = 'absolute';
164 | this.overlay.style.top = '0';
165 | this.overlay.style.left = '0';
166 | // this.overlay.style.zIndex = '2';
167 | this.overlay.style.width = '100%';
168 | this.overlay.style.height = '100%';
169 | this.overlay.style.objectFit = 'contain';
170 | this.context = this.overlay.getContext('2d');
171 | container.appendChild(this.overlay);
172 | };
173 | DBRWrapper.prototype.appendCameraSource = function (deviceInfos) {
174 | for (var i = 0; i < deviceInfos.length; ++i) {
175 | var deviceInfo = deviceInfos[i];
176 | var option = document.createElement('option');
177 | option.value = deviceInfo.deviceId;
178 | option.text = deviceInfo.label;
179 | this.cameraInfo[deviceInfo.deviceId] = deviceInfo;
180 | this.selectElement.appendChild(option);
181 | }
182 | };
183 | DBRWrapper.prototype.initCameraSource = function () {
184 | this.cameraSourceElement = document.createElement('div');
185 | this.selectElement = document.createElement('select');
186 | this.selectElement.onchange = this.openCamera;
187 | this.cameraSourceElement.appendChild(this.selectElement);
188 | };
189 | DBRWrapper.prototype.onCameraReady = function () {
190 | var resolution = this.scanner.getResolution();
191 | this.updateOverlay(resolution[0], resolution[1]);
192 | };
193 | DBRWrapper.prototype.openCamera = function () {
194 | return __awaiter(this, void 0, void 0, function () {
195 | var deviceId;
196 | return __generator(this, function (_a) {
197 | switch (_a.label) {
198 | case 0:
199 | this.clearOverlay();
200 | deviceId = this.selectElement.value;
201 | if (!this.scanner) return [3 /*break*/, 2];
202 | return [4 /*yield*/, this.scanner.setCurrentCamera(this.cameraInfo[deviceId])];
203 | case 1:
204 | _a.sent();
205 | _a.label = 2;
206 | case 2: return [2 /*return*/];
207 | }
208 | });
209 | });
210 | };
211 | DBRWrapper.prototype.initCameraView = function () {
212 | this.cameraViewElement = document.createElement('div');
213 | this.cameraViewElement.style.position = 'relative';
214 | this.cameraViewElement.style.width = '100vw';
215 | this.cameraViewElement.style.height = '100vh';
216 | this.videoContainer = document.createElement('div');
217 | this.videoContainer.style.position = 'relative';
218 | this.videoContainer.style.width = '100%';
219 | this.videoContainer.style.height = '100%';
220 | this.videoContainer.style.zIndex = '1';
221 | this.videoContainer.className = "dce-video-container";
222 | this.cameraViewElement.appendChild(this.videoContainer);
223 | this.overlay = document.createElement('canvas');
224 | this.overlay.style.position = 'absolute';
225 | this.overlay.style.top = '0';
226 | this.overlay.style.left = '0';
227 | this.overlay.style.zIndex = '2';
228 | this.overlay.style.width = '100%';
229 | this.overlay.style.height = '100%';
230 | this.overlay.style.objectFit = 'contain';
231 | this.context = this.overlay.getContext('2d');
232 | this.cameraViewElement.appendChild(this.overlay);
233 | };
234 | DBRWrapper.prototype.getCameraSource = function () {
235 | return this.cameraSourceElement;
236 | };
237 | DBRWrapper.prototype.getCameraView = function () {
238 | return this.cameraViewElement;
239 | };
240 | DBRWrapper.prototype.updateOverlay = function (width, height) {
241 | if (this.overlay) {
242 | this.overlay.width = width;
243 | this.overlay.height = height;
244 | this.clearOverlay();
245 | }
246 | };
247 | DBRWrapper.prototype.clearOverlay = function () {
248 | if (this.context) {
249 | this.context.clearRect(0, 0, this.overlay.width, this.overlay.height);
250 | this.context.strokeStyle = '#ff0000';
251 | this.context.lineWidth = 5;
252 | }
253 | };
254 | DBRWrapper.prototype.drawOverlay = function (localization, text) {
255 | if (this.context) {
256 | this.context.beginPath();
257 | this.context.moveTo(localization.x1, localization.y1);
258 | this.context.lineTo(localization.x2, localization.y2);
259 | this.context.lineTo(localization.x3, localization.y3);
260 | this.context.lineTo(localization.x4, localization.y4);
261 | this.context.lineTo(localization.x1, localization.y1);
262 | this.context.stroke();
263 | this.context.font = '18px Verdana';
264 | this.context.fillStyle = '#ff0000';
265 | var x = [localization.x1, localization.x2, localization.x3, localization.x4];
266 | var y = [localization.y1, localization.y2, localization.y3, localization.y4];
267 | x.sort(function (a, b) {
268 | return a - b;
269 | });
270 | y.sort(function (a, b) {
271 | return b - a;
272 | });
273 | var left = x[0];
274 | var top_1 = y[0];
275 | this.context.fillText(text, left, top_1 + 50);
276 | }
277 | };
278 | DBRWrapper.prototype.showOverlay = function () {
279 | this.overlay.style.display = 'block';
280 | document.getElementsByClassName('cvs-scan-region-overlay-0')[0].style.display = 'block';
281 | };
282 | DBRWrapper.prototype.hideOverlay = function () {
283 | this.overlay.style.display = 'none';
284 | document.getElementsByClassName('cvs-scan-region-overlay-0')[0].style.display = 'none';
285 | };
286 | DBRWrapper.prototype.showCamera = function () {
287 | if (this.scanner) {
288 | this.scanner.show();
289 | }
290 | };
291 | DBRWrapper.prototype.hideCamera = function () {
292 | if (this.scanner) {
293 | this.scanner.hide();
294 | }
295 | };
296 | // Dynamically load Dynamsoft Barcode Reader JS library
297 | DBRWrapper.prototype.loadDBR = function (callback) {
298 | var script = document.createElement('script');
299 | script.src = "https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.0.2/dist/dbr.js";
300 | script.onload = function () {
301 | callback(Dynamsoft);
302 | };
303 | document.head.appendChild(script);
304 | };
305 | DBRWrapper.prototype.constructView = function () {
306 | document.body.appendChild(this.getCameraSource());
307 | document.body.appendChild(this.getCameraView());
308 | };
309 | return DBRWrapper;
310 | }());
311 |
--------------------------------------------------------------------------------
/examples/9.x/dbr-scanner-wrapper.ts:
--------------------------------------------------------------------------------
1 | class DBRWrapper {
2 | private scanner: Dynamsoft.DBR.BarcodeScanner;
3 | private videoContainer: HTMLDivElement;
4 | private cameraSourceElement: HTMLDivElement;
5 | private cameraViewElement: HTMLDivElement;
6 | private overlay: HTMLCanvasElement;
7 | private context: CanvasRenderingContext2D;
8 | private selectElement: HTMLSelectElement;
9 | private cameraInfo: any;
10 |
11 | constructor() {
12 | try {
13 | this.scanner = null;
14 | this.videoContainer = null;
15 | this.cameraSourceElement = null;
16 | this.cameraViewElement = null;
17 | this.overlay = null;
18 | this.context = null;
19 | this.selectElement = null;
20 | this.cameraInfo = {};
21 | this.openCamera = this.openCamera.bind(this);
22 | this.onCameraReady = this.onCameraReady.bind(this);
23 | }
24 | catch (ex) {
25 | alert(ex.message);
26 | throw ex;
27 | }
28 | }
29 |
30 | async createCustomScanner(callback) {
31 | this.initCameraSource();
32 | this.initCameraView();
33 |
34 | await Dynamsoft.DBR.BarcodeScanner.loadWasm();
35 | this.scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
36 | await this.scanner.updateRuntimeSettings("speed");
37 | await this.scanner.setUIElement(this.videoContainer);
38 | let cameras = await this.scanner.getAllCameras();
39 | this.appendCameraSource(cameras);
40 | await this.openCamera();
41 | this.scanner.onFrameRead = results => {
42 | this.clearOverlay();
43 |
44 | let txts = [];
45 | let localization;
46 | if (results.length > 0) {
47 | for (var i = 0; i < results.length; ++i) {
48 | txts.push(results[i].barcodeText);
49 | localization = results[i].localizationResult;
50 | this.drawOverlay(localization, results[i].barcodeText);
51 | }
52 |
53 | if (callback) {
54 | callback(txts.join(', '));
55 | }
56 | }
57 | else {
58 | if (callback) {
59 | callback("No barcode found");
60 | }
61 | }
62 | };
63 | this.scanner.onUnduplicatedRead = (txt, result) => { };
64 | this.scanner.onPlayed = this.onCameraReady;
65 | return this.scanner;
66 | }
67 |
68 | async createDefaultScanner(callback) {
69 | this.scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
70 | await this.scanner.updateRuntimeSettings("speed");
71 | this.scanner.onFrameRead = results => {
72 | this.clearOverlay();
73 |
74 | let txts = [];
75 | let localization;
76 | if (results.length > 0) {
77 | for (var i = 0; i < results.length; ++i) {
78 | txts.push(results[i].barcodeText);
79 | localization = results[i].localizationResult;
80 | this.drawOverlay(localization, results[i].barcodeText);
81 | }
82 | }
83 |
84 | if (callback) {
85 | callback(results);
86 | }
87 | };
88 | this.scanner.onUnduplicatedRead = (txt, result) => { };
89 | this.scanner.onPlayed = this.onCameraReady;
90 | return this.scanner;
91 | }
92 |
93 | patchOverlay() {
94 | let containers = document.getElementsByClassName("dce-video-container");
95 |
96 | if (containers == null || containers.length == 0) {
97 | return;
98 | }
99 |
100 | // Always select last element.
101 | let container = document.getElementsByClassName("dce-video-container")[containers.length - 1];
102 | let lastElement = container.lastElementChild;
103 |
104 | if (lastElement && lastElement.id === "custom-overlay")
105 | container.removeChild(lastElement);
106 |
107 | this.overlay = document.createElement('canvas');
108 | this.overlay.id = "custom-overlay";
109 | this.overlay.style.position = 'absolute';
110 | this.overlay.style.top = '0';
111 | this.overlay.style.left = '0';
112 | // this.overlay.style.zIndex = '2';
113 | this.overlay.style.width = '100%';
114 | this.overlay.style.height = '100%';
115 | this.overlay.style.objectFit = 'contain';
116 | this.context = this.overlay.getContext('2d');
117 | container.appendChild(this.overlay);
118 | }
119 |
120 | appendCameraSource(deviceInfos) {
121 | for (var i = 0; i < deviceInfos.length; ++i) {
122 | var deviceInfo = deviceInfos[i];
123 | var option = document.createElement('option');
124 | option.value = deviceInfo.deviceId;
125 | option.text = deviceInfo.label;
126 | this.cameraInfo[deviceInfo.deviceId] = deviceInfo;
127 | this.selectElement.appendChild(option);
128 | }
129 | }
130 |
131 | initCameraSource() {
132 | this.cameraSourceElement = document.createElement('div');
133 | this.selectElement = document.createElement('select');
134 | this.selectElement.onchange = this.openCamera;
135 | this.cameraSourceElement.appendChild(this.selectElement);
136 | }
137 |
138 | onCameraReady() {
139 | let resolution = this.scanner.getResolution();
140 | this.updateOverlay(resolution[0], resolution[1]);
141 | }
142 |
143 | async openCamera() {
144 | this.clearOverlay();
145 | let deviceId = this.selectElement.value;
146 | if (this.scanner) {
147 | await this.scanner.setCurrentCamera(this.cameraInfo[deviceId]);
148 | }
149 | }
150 |
151 | initCameraView() {
152 | this.cameraViewElement = document.createElement('div');
153 | this.cameraViewElement.style.position = 'relative';
154 | this.cameraViewElement.style.width = '100vw';
155 | this.cameraViewElement.style.height = '100vh';
156 |
157 | this.videoContainer = document.createElement('div');
158 | this.videoContainer.style.position = 'relative';
159 | this.videoContainer.style.width = '100%';
160 | this.videoContainer.style.height = '100%';
161 | this.videoContainer.style.zIndex = '1';
162 | this.videoContainer.className = "dce-video-container";
163 | this.cameraViewElement.appendChild(this.videoContainer);
164 |
165 | this.overlay = document.createElement('canvas');
166 | this.overlay.style.position = 'absolute';
167 | this.overlay.style.top = '0';
168 | this.overlay.style.left = '0';
169 | this.overlay.style.zIndex = '2';
170 | this.overlay.style.width = '100%';
171 | this.overlay.style.height = '100%';
172 | this.overlay.style.objectFit = 'contain';
173 | this.context = this.overlay.getContext('2d');
174 |
175 | this.cameraViewElement.appendChild(this.overlay);
176 | }
177 |
178 | getCameraSource() {
179 | return this.cameraSourceElement;
180 | }
181 |
182 | getCameraView() {
183 | return this.cameraViewElement;
184 | }
185 |
186 | updateOverlay(width, height) {
187 | if (this.overlay) {
188 | this.overlay.width = width;
189 | this.overlay.height = height;
190 | this.clearOverlay();
191 | }
192 | }
193 |
194 | clearOverlay() {
195 | if (this.context) {
196 | this.context.clearRect(0, 0, this.overlay.width, this.overlay.height);
197 | this.context.strokeStyle = '#ff0000';
198 | this.context.lineWidth = 5;
199 | }
200 | }
201 |
202 | drawOverlay(localization, text) {
203 | if (this.context) {
204 | this.context.beginPath();
205 | this.context.moveTo(localization.x1, localization.y1);
206 | this.context.lineTo(localization.x2, localization.y2);
207 | this.context.lineTo(localization.x3, localization.y3);
208 | this.context.lineTo(localization.x4, localization.y4);
209 | this.context.lineTo(localization.x1, localization.y1);
210 | this.context.stroke();
211 |
212 | this.context.font = '18px Verdana';
213 | this.context.fillStyle = '#ff0000';
214 | let x = [localization.x1, localization.x2, localization.x3, localization.x4];
215 | let y = [localization.y1, localization.y2, localization.y3, localization.y4];
216 | x.sort(function (a, b) {
217 | return a - b;
218 | });
219 | y.sort(function (a, b) {
220 | return b - a;
221 | });
222 | let left = x[0];
223 | let top = y[0];
224 |
225 | this.context.fillText(text, left, top + 50);
226 | }
227 | }
228 |
229 | showOverlay() {
230 | this.overlay.style.display = 'block';
231 | document.getElementsByClassName('cvs-scan-region-overlay-0')[0].style.display = 'block';
232 | }
233 |
234 | hideOverlay() {
235 | this.overlay.style.display = 'none';
236 | document.getElementsByClassName('cvs-scan-region-overlay-0')[0].style.display = 'none';
237 | }
238 |
239 | showCamera() {
240 | if (this.scanner) {
241 | this.scanner.show();
242 | }
243 | }
244 |
245 | hideCamera() {
246 | if (this.scanner) {
247 | this.scanner.hide();
248 | }
249 | }
250 |
251 | static createInstance() : DBRWrapper {
252 | return new DBRWrapper();
253 | }
254 |
255 | // Dynamically load Dynamsoft Barcode Reader JS library
256 | loadDBR(callback) {
257 | let script = document.createElement('script');
258 | script.src = "https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.0.2/dist/dbr.js";
259 | script.onload = function () {
260 | callback(Dynamsoft);
261 | };
262 | document.head.appendChild(script);
263 | }
264 |
265 | constructView() {
266 | document.body.appendChild(this.getCameraSource());
267 | document.body.appendChild(this.getCameraView());
268 | }
269 | }
--------------------------------------------------------------------------------
/examples/9.x/driver_license/README.md:
--------------------------------------------------------------------------------
1 | # Driver License PDF417 Scanner in JavaScript
2 | This sample demonstrates how to read and extract driver's license information from PDF417 barcodes using the Dynamsoft [JavaScript barcode SDK](https://www.dynamsoft.com/barcode-reader/sdk-javascript/).
3 |
4 | ## Usage
5 | 1. Obtain a [free trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform) and update the following code:
6 |
7 | ```js
8 | Dynamsoft.DBR.BarcodeReader.license = "LICENSE-KEY";
9 | ```
10 |
11 | 2. Deploy the project to a web server and then open the driver's license scanner in a web browser:
12 |
13 | ```bash
14 | python -m http.server
15 | ```
16 |
17 | 
18 |
19 | ## Online Demo
20 | [https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/driver_license/](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/driver_license/)
21 |
22 | ## References
23 | - https://www.aamva.org/DL-ID-Card-Design-Standard/
24 | - https://github.com/Dynamsoft/javascript-barcode/tree/master/example/web/decode-driver-license-for-AAMVA
25 |
26 | ## Blog
27 | [Reading Driver’s License Information from PDF417 in JavaScript](https://www.dynamsoft.com/codepool/javascript-driver-license-pdf417-web.html)
28 |
--------------------------------------------------------------------------------
/examples/9.x/driver_license/driverlicense.js:
--------------------------------------------------------------------------------
1 | // AAMVA2016, driver license abbreviation-description map
2 | const DLAbbrDesMap = {
3 | 'DCA': 'Jurisdiction-specific vehicle class',
4 | 'DBA': 'Expiry Date',
5 | 'DCS': 'Last Name',
6 | 'DAC': 'First Name',
7 | 'DBD': 'Issue Date',
8 | 'DBB': 'Birth Date',
9 | 'DBC': 'Gender',
10 | 'DAY': 'Eye Color',
11 | 'DAU': 'Height',
12 | 'DAG': 'Street',
13 | 'DAI': 'City',
14 | 'DAJ': 'State',
15 | 'DAK': 'Zip',
16 | 'DAQ': 'License Number',
17 | 'DCF': 'Document Discriminator',
18 | 'DCG': 'Issue Country',
19 | 'DAH': 'Street 2',
20 | 'DAZ': 'Hair Color',
21 | 'DCI': 'Place of birth',
22 | 'DCJ': 'Audit information',
23 | 'DCK': 'Inventory Control Number',
24 | 'DBN': 'Alias / AKA Family Name',
25 | 'DBG': 'Alias / AKA Given Name',
26 | 'DBS': 'Alias / AKA Suffix Name',
27 | 'DCU': 'Name Suffix',
28 | 'DCE': 'Physical Description Weight Range',
29 | 'DCL': 'Race / Ethnicity',
30 | 'DCM': 'Standard vehicle classification',
31 | 'DCN': 'Standard endorsement code',
32 | 'DCO': 'Standard restriction code',
33 | 'DCP': 'Jurisdiction-specific vehicle classification description',
34 | 'DCQ': 'Jurisdiction-specific endorsement code description',
35 | 'DCR': 'Jurisdiction-specific restriction code description',
36 | 'DDA': 'Compliance Type',
37 | 'DDB': 'Card Revision Date',
38 | 'DDC': 'HazMat Endorsement Expiration Date',
39 | 'DDD': 'Limited Duration Document Indicator',
40 | 'DAW': 'Weight(pounds)',
41 | 'DAX': 'Weight(kilograms)',
42 | 'DDH': 'Under 18 Until',
43 | 'DDI': 'Under 19 Until',
44 | 'DDJ': 'Under 21 Until',
45 | 'DDK': 'Organ Donor Indicator',
46 | 'DDL': 'Veteran Indicator',
47 | // old standard
48 | 'DAA': 'Customer Full Name',
49 | 'DAB': 'Customer Last Name',
50 | 'DAE': 'Name Suffix',
51 | 'DAF': 'Name Prefix',
52 | 'DAL': 'Residence Street Address1',
53 | 'DAM': 'Residence Street Address2',
54 | 'DAN': 'Residence City',
55 | 'DAO': 'Residence Jurisdiction Code',
56 | 'DAR': 'License Classification Code',
57 | 'DAS': 'License Restriction Code',
58 | 'DAT': 'License Endorsements Code',
59 | 'DAV': 'Height in CM',
60 | 'DBE': 'Issue Timestamp',
61 | 'DBF': 'Number of Duplicates',
62 | 'DBH': 'Organ Donor',
63 | 'DBI': 'Non-Resident Indicator',
64 | 'DBJ': 'Unique Customer Identifier',
65 | 'DBK': 'Social Security Number',
66 | 'DBM': 'Social Security Number',
67 | 'DCH': 'Federal Commercial Vehicle Codes',
68 | 'DBR': 'Name Suffix',
69 | 'PAA': 'Permit Classification Code',
70 | 'PAB': 'Permit Expiration Date',
71 | 'PAC': 'Permit Identifier',
72 | 'PAD': 'Permit IssueDate',
73 | 'PAE': 'Permit Restriction Code',
74 | 'PAF': 'Permit Endorsement Code',
75 | 'ZVA': 'Court Restriction Code',
76 | 'DAD': 'Middle Name'
77 | };
78 |
79 | // Get driver license abbreviation-content map from raw txt
80 | var parseDriverLicense = txt => {
81 | console.log(txt);
82 | let lines = txt.split('\n');
83 | let abbrs = Object.keys(DLAbbrDesMap);
84 | let map = {};
85 | lines.forEach((line, i) => {
86 | let abbr;
87 | let content;
88 | if(i === 1){
89 | abbr = 'DAQ';
90 | content = line.substring(line.indexOf(abbr) + 3);
91 | }else{
92 | abbr = line.substring(0, 3);
93 | content = line.substring(3).trim();
94 | }
95 | if(abbrs.includes(abbr)){
96 | map[abbr] = {
97 | description: DLAbbrDesMap[abbr],
98 | content: content
99 | };
100 | }
101 | });
102 | return map;
103 | };
104 |
--------------------------------------------------------------------------------
/examples/9.x/driver_license/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
38 |
39 |
40 |
41 |
42 | Loading Library...
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
54 |
55 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/examples/9.x/hello-world.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Scanner
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/9.x/manually-load.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Scanner
8 |
9 |
10 |
11 |
12 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/examples/9.x/overlay.js:
--------------------------------------------------------------------------------
1 | var overlay = null;
2 | var context = null;
3 |
4 | function initOverlay(ol) {
5 | overlay = ol;
6 | context = overlay.getContext('2d');
7 | }
8 |
9 | function updateOverlay(width, height) {
10 | if (overlay) {
11 | overlay.width = width;
12 | overlay.height = height;
13 | clearOverlay();
14 | }
15 | }
16 |
17 | function clearOverlay() {
18 | if (context) {
19 | context.clearRect(0, 0, overlay.width, overlay.height);
20 | context.strokeStyle = '#ff0000';
21 | context.lineWidth = 5;
22 | }
23 | }
24 |
25 | function drawOverlay(localization, text) {
26 | if (context) {
27 | context.beginPath();
28 | context.moveTo(localization.x1, localization.y1);
29 | context.lineTo(localization.x2, localization.y2);
30 | context.lineTo(localization.x3, localization.y3);
31 | context.lineTo(localization.x4, localization.y4);
32 | context.lineTo(localization.x1, localization.y1);
33 | context.stroke();
34 |
35 | context.font = '18px Verdana';
36 | context.fillStyle = '#ff0000';
37 | let x = [localization.x1, localization.x2, localization.x3, localization.x4];
38 | let y = [localization.y1, localization.y2, localization.y3, localization.y4];
39 | x.sort(function (a, b) {
40 | return a - b;
41 | });
42 | y.sort(function (a, b) {
43 | return b - a;
44 | });
45 | let left = x[0];
46 | let top = y[0];
47 |
48 | context.fillText(text, left, top + 50);
49 | }
50 | }
51 |
52 | function drawQuad(points) {
53 | if (context) {
54 | context.beginPath();
55 | context.moveTo(points[0].x, points[0].y);
56 | context.lineTo(points[1].x, points[1].y);
57 | context.lineTo(points[2].x, points[2].y);
58 | context.lineTo(points[3].x, points[3].y);
59 | context.lineTo(points[0].x, points[0].y);
60 | context.stroke();
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/examples/9.x/pwa/README.md:
--------------------------------------------------------------------------------
1 | # Barcode Reader PWA
2 |
3 | The sample demonstrates how to integrate [Dynamsoft JavaScript Barcode SDK](https://www.dynamsoft.com/barcode-reader/sdk-javascript/) into a progressive web app.
4 |
5 | ## License
6 | Get a [30-day FREE trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform).
7 |
8 | ## Usage
9 | 1. Set a valid license key:
10 |
11 | ```js
12 | Dynamsoft.DBR.BarcodeReader.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
13 | ```
14 | 2. Deploy the PWA project to a web server.
15 |
16 | 
17 |
18 | ## Online Demo
19 | https://yushulx.me/javascript-barcode-qr-code-scanner/pwa
20 |
21 |
22 | ## Blog
23 | [How to Build a Simple PWA Barcode Reader](https://www.codepool.biz/build-simple-pwa-barcode-reader.html)
24 |
--------------------------------------------------------------------------------
/examples/9.x/pwa/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/favicon.ico
--------------------------------------------------------------------------------
/examples/9.x/pwa/icons/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/icons/icon-128.png
--------------------------------------------------------------------------------
/examples/9.x/pwa/icons/icon-144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/icons/icon-144.png
--------------------------------------------------------------------------------
/examples/9.x/pwa/icons/icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/icons/icon-152.png
--------------------------------------------------------------------------------
/examples/9.x/pwa/icons/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/icons/icon-192.png
--------------------------------------------------------------------------------
/examples/9.x/pwa/icons/icon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/icons/icon-256.png
--------------------------------------------------------------------------------
/examples/9.x/pwa/icons/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/pwa/icons/icon-32.png
--------------------------------------------------------------------------------
/examples/9.x/pwa/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Dynamsoft Barcode Reader
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Barcode Result:
N/A
24 |
25 |
26 | Loading Library...
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/examples/9.x/pwa/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "BarcodeScanner",
3 | "short_name": "BarcodeScanner",
4 | "description": "A progressive web app for reading barcode and QR code.",
5 | "icons": [
6 | {
7 | "src": "icons/icon-192.png",
8 | "sizes": "192x192",
9 | "type": "image/png"
10 | }
11 | ],
12 | "start_url": "./",
13 | "display": "standalone",
14 | "theme_color": "#2F3BA2",
15 | "background_color": "#3E4EB8"
16 | }
--------------------------------------------------------------------------------
/examples/9.x/pwa/overlay.js:
--------------------------------------------------------------------------------
1 | var overlay = null;
2 | var context = null;
3 |
4 | function initOverlay(ol) {
5 | overlay = ol;
6 | context = overlay.getContext('2d');
7 | }
8 |
9 | function updateOverlay(width, height) {
10 | if (overlay) {
11 | overlay.width = width;
12 | overlay.height = height;
13 | clearOverlay();
14 | }
15 | }
16 |
17 | function clearOverlay() {
18 | if (context) {
19 | context.clearRect(0, 0, overlay.width, overlay.height);
20 | context.strokeStyle = '#ff0000';
21 | context.lineWidth = 5;
22 | }
23 | }
24 |
25 | function drawOverlay(localization, text) {
26 | if (context) {
27 | context.beginPath();
28 | context.moveTo(localization.x1, localization.y1);
29 | context.lineTo(localization.x2, localization.y2);
30 | context.lineTo(localization.x3, localization.y3);
31 | context.lineTo(localization.x4, localization.y4);
32 | context.lineTo(localization.x1, localization.y1);
33 | context.stroke();
34 |
35 | context.font = '18px Verdana';
36 | context.fillStyle = '#ff0000';
37 | let x = [localization.x1, localization.x2, localization.x3, localization.x4];
38 | let y = [localization.y1, localization.y2, localization.y3, localization.y4];
39 | x.sort(function (a, b) {
40 | return a - b;
41 | });
42 | y.sort(function (a, b) {
43 | return b - a;
44 | });
45 | let left = x[0];
46 | let top = y[0];
47 |
48 | context.fillText(text, left, top + 50);
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/examples/9.x/pwa/service-worker.js:
--------------------------------------------------------------------------------
1 | self.addEventListener('fetch', event => {
2 |
3 | if (event.request.method !== 'GET') return;
4 |
5 | return;
6 | });
--------------------------------------------------------------------------------
/examples/9.x/pwa/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | }
6 |
7 | #videoview {
8 | position: relative;
9 | width: 90%;
10 | height: 64vh;
11 | }
12 |
13 | #videoContainer {
14 | position: relative;
15 | width: 100%;
16 | height: 100%;
17 | z-index: 1
18 | }
19 |
20 | #overlay {
21 | position: absolute;
22 | top: 0;
23 | left: 0;
24 | width: 100%;
25 | height: 100%;
26 | z-index: 2;
27 | object-fit: contain
28 | }
--------------------------------------------------------------------------------
/examples/9.x/qr-code-scanner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Scanner
8 |
9 |
10 |
47 |
48 |
49 |
50 |
51 | Barcode Result:
N/A
52 |
53 |
54 | Loading Library...
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
66 |
67 |
160 |
161 |
162 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.eslintignore:
--------------------------------------------------------------------------------
1 | **/lwc/**/*.css
2 | **/lwc/**/*.html
3 | **/lwc/**/*.json
4 | **/lwc/**/*.svg
5 | **/lwc/**/*.xml
6 | **/aura/**/*.auradoc
7 | **/aura/**/*.cmp
8 | **/aura/**/*.css
9 | **/aura/**/*.design
10 | **/aura/**/*.evt
11 | **/aura/**/*.json
12 | **/aura/**/*.svg
13 | **/aura/**/*.tokens
14 | **/aura/**/*.xml
15 | .sfdx
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 | .localdevserver/
8 |
9 | # LWC VSCode autocomplete
10 | **/lwc/jsconfig.json
11 |
12 | # LWC Jest coverage reports
13 | coverage/
14 |
15 | # Logs
16 | logs
17 | *.log
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
22 | # Dependency directories
23 | node_modules/
24 |
25 | # Eslint cache
26 | .eslintcache
27 |
28 | # MacOS system files
29 | .DS_Store
30 |
31 | # Windows system files
32 | Thumbs.db
33 | ehthumbs.db
34 | [Dd]esktop.ini
35 | $RECYCLE.BIN/
36 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.prettierignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running prettier
2 | # More information: https://prettier.io/docs/en/ignore.html
3 | #
4 |
5 | **/staticresources/**
6 | .localdevserver
7 | .sfdx
8 | .vscode
9 |
10 | coverage/
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "overrides": [
4 | {
5 | "files": "**/lwc/**/*.html",
6 | "options": { "parser": "lwc" }
7 | },
8 | {
9 | "files": "*.{cmp,page,component}",
10 | "options": { "parser": "html" }
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "salesforce.salesforcedx-vscode",
4 | "redhat.vscode-xml",
5 | "dbaeumer.vscode-eslint",
6 | "esbenp.prettier-vscode"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Launch Apex Replay Debugger",
9 | "type": "apex-replay",
10 | "request": "launch",
11 | "logFile": "${command:AskForLogFileName}",
12 | "stopOnEntry": true,
13 | "trace": true
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.exclude": {
3 | "**/node_modules": true,
4 | "**/bower_components": true,
5 | "**/.sfdx": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/README.md:
--------------------------------------------------------------------------------
1 | # 1D/2D Barcode Detection in Salesforce Visualforce Page
2 |
3 | This sample demonstrates how to integrate the [Dynamsoft JavaScript Barcode SDK](https://www.dynamsoft.com/barcode-reader/sdk-javascript/) into **Salesforce Visualforce pages** for efficient barcode detection.
4 |
5 | ## Prerequisites
6 | - Obtain a [30-day FREE trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform) to try out the SDK.
7 |
8 | ## Getting Started
9 | Follow these steps to set up the project:
10 | 1. Open the project in Visual Studio Code.
11 | 2. Replace `LICENSE-KEY` with your own license key in the code:
12 |
13 | ```js
14 | Dynamsoft.DBR.BarcodeReader.license = "LICENSE-KEY";
15 | ```
16 | 3. Authorize the project within your Salesforce organization.
17 | 4. Deploy the source files to your Salesforce organization.
18 | 5. Test the barcode detection by previewing the Visualforce pages within the Salesforce environment.
19 |
20 | 
21 |
22 | 
23 |
24 |
25 | ## Blog
26 | [Step-by-Step Guide to Creating a Barcode Reader App for Salesforce AppExchange](https://www.dynamsoft.com/codepool/salesforce-appexchange-barcode-reader-app.html)
27 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/config/project-scratch-def.json:
--------------------------------------------------------------------------------
1 | {
2 | "orgName": "Dynamsoft",
3 | "edition": "Developer",
4 | "features": [],
5 | "settings": {
6 | "lightningExperienceSettings": {
7 | "enableS1DesktopEnabled": true
8 | },
9 | "securitySettings": {
10 | "passwordPolicies": {
11 | "enableSetPasswordInApi": true
12 | }
13 | },
14 | "mobileSettings": {
15 | "enableS1EncryptedStoragePref2": false
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/aura/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["@salesforce/eslint-plugin-aura"],
3 | "extends": ["plugin:@salesforce/eslint-plugin-aura/recommended", "prettier"],
4 | "rules": {
5 | "func-names": "off",
6 | "vars-on-top": "off",
7 | "no-unused-expressions": "off"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/lwc/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@salesforce/eslint-config-lwc/recommended", "prettier"],
3 | "overrides": [
4 | {
5 | "files": ["*.test.js"],
6 | "rules": {
7 | "@lwc/lwc/no-unexpected-wire-adapter-usages": "off"
8 | }
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/pages/DecodeFile.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Dynamsoft JavaScript Barcode SDK
9 |
10 |
11 |
12 |
13 |
![]()
14 |
15 |
16 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/pages/DecodeFile.page:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Dynamsoft JavaScript Barcode SDK
10 |
11 |
12 |
13 |
14 |
![]()
15 |
16 |
17 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/pages/DecodeFile.page-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 49.0
4 |
5 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/pages/DecodeVideo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
21 |
22 | Dynamsoft JavaScript Barcode SDK
23 |
24 |
28 |
29 |
30 |
31 |
32 | N/A
33 |
36 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/pages/DecodeVideo.page:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
20 |
21 |
22 |
23 | Dynamsoft JavaScript Barcode SDK
24 |
25 |
29 |
30 |
31 |
32 |
33 | N/A
34 |
37 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/force-app/main/default/pages/DecodeVideo.page-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 49.0
4 |
5 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "salesforce-app",
3 | "private": true,
4 | "version": "1.0.0",
5 | "description": "Salesforce App",
6 | "scripts": {
7 | "lint": "npm run lint:lwc && npm run lint:aura",
8 | "lint:aura": "eslint **/aura/**",
9 | "lint:lwc": "eslint **/lwc/**",
10 | "test": "npm run test:unit",
11 | "test:unit": "sfdx-lwc-jest",
12 | "test:unit:watch": "sfdx-lwc-jest --watch",
13 | "test:unit:debug": "sfdx-lwc-jest --debug",
14 | "test:unit:coverage": "sfdx-lwc-jest --coverage",
15 | "prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
16 | "prettier:verify": "prettier --list-different \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\""
17 | },
18 | "devDependencies": {
19 | "@prettier/plugin-xml": "^0.10.0",
20 | "@salesforce/eslint-config-lwc": "^0.7.0",
21 | "@salesforce/eslint-plugin-aura": "^1.4.0",
22 | "@salesforce/sfdx-lwc-jest": "^0.9.2",
23 | "eslint": "^7.6.0",
24 | "eslint-config-prettier": "^6.11.0",
25 | "husky": "^4.2.1",
26 | "lint-staged": "^10.0.7",
27 | "prettier": "^2.0.5",
28 | "prettier-plugin-apex": "^1.6.0"
29 | },
30 | "husky": {
31 | "hooks": {
32 | "pre-commit": "lint-staged"
33 | }
34 | },
35 | "lint-staged": {
36 | "**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}": [
37 | "prettier --write"
38 | ],
39 | "**/{aura|lwc}/**": [
40 | "eslint"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/scripts/apex/hello.apex:
--------------------------------------------------------------------------------
1 | // Use .apex files to store anonymous Apex.
2 | // You can execute anonymous Apex in VS Code by selecting the
3 | // apex text and running the command:
4 | // SFDX: Execute Anonymous Apex with Currently Selected Text
5 | // You can also execute the entire file by running the command:
6 | // SFDX: Execute Anonymous Apex with Editor Contents
7 |
8 | string tempvar = 'Enter_your_name_here';
9 | System.debug('Hello World!');
10 | System.debug('My name is ' + tempvar);
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/scripts/soql/account.soql:
--------------------------------------------------------------------------------
1 | // Use .soql files to store SOQL queries.
2 | // You can execute queries in VS Code by selecting the
3 | // query text and running the command:
4 | // SFDX: Execute SOQL Query with Currently Selected Text
5 |
6 | SELECT Id, Name FROM Account
7 |
--------------------------------------------------------------------------------
/examples/9.x/salesforce_visualforce_page/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "49.0"
11 | }
12 |
--------------------------------------------------------------------------------
/examples/9.x/ui-customization.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Scanner
8 |
9 |
45 |
46 |
47 |
48 |
49 | Barcode Result:
N/A
50 |
51 |
52 | Loading Library...
53 |
54 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/examples/9.x/webgl/README.md:
--------------------------------------------------------------------------------
1 | # JavaScript Barcode and QR Code Reader: WebGL vs. Canvas
2 | Use WebGL to convert color images to grayscale, speeding up barcode and QR code decoding in JavaScript.
3 |
4 | ## License Activation
5 | Get a [trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform) to activate the [JavaScript barcode SDK](https://www.dynamsoft.com/barcode-reader/sdk-javascript/):
6 |
7 | ```javascript
8 | Dynamsoft.DBR.BarcodeReader.license = "LICENSE-KEY";
9 | ```
10 |
11 | ## Try Example
12 | [https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/webgl/](https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/webgl/)
13 |
14 | 
15 |
16 | ## References
17 | - https://webglfundamentals.org/webgl/lessons/webgl-2d-drawimage.html
18 | - https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D
19 |
20 | ## Blog
21 | [How to Use WebGL to Accelerate Web Barcode Decoding Speed](https://www.dynamsoft.com/codepool/webgl-accelerate-web-barcode-decoding-speed.html)
22 |
--------------------------------------------------------------------------------
/examples/9.x/webgl/grayscale-image/640x480.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/webgl/grayscale-image/640x480.jpg
--------------------------------------------------------------------------------
/examples/9.x/webgl/grayscale-image/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | WebGL - 2D - DrawImage basic
9 |
10 |
11 |
12 |
13 |
14 |
27 |
28 |
42 |
49 |
50 |
51 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/examples/9.x/webgl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
34 |
35 |
36 |
37 |
38 | Web Barcode Scanning with WebGL
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
72 |
73 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/9.x/webgl/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/9.x/webgl/loading.gif
--------------------------------------------------------------------------------
/examples/9.x/webgl/util.js:
--------------------------------------------------------------------------------
1 | // Make sure to set the key before you call any other APIs under Dynamsoft.DBR
2 | //You can register for a free 30-day trial here: https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform
3 | Dynamsoft.DBR.BarcodeReader.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
4 |
5 | var barcodereader;
6 | var barcode_result = document.getElementById('barcode_result');
7 | (async () => {
8 | barcodereader = await Dynamsoft.DBR.BarcodeReader.createInstance();
9 | await barcodereader.updateRuntimeSettings('speed');
10 | let settings = await barcodereader.getRuntimeSettings();
11 | settings.deblurLevel = 0;
12 | barcodereader.updateRuntimeSettings(settings);
13 |
14 | document.getElementById('anim-loading').style.display = 'none';
15 | btWebGL.disabled = false;
16 | btCanvas.disabled = false;
17 | })();
18 |
19 | var videoSelect = document.querySelector('select#videoSource');
20 | var videoOption = document.getElementById('videoOption');
21 | var btWebGL = document.getElementById('bt-webgl');
22 | btWebGL.disabled = true;
23 | var btCanvas = document.getElementById('bt-canvas');
24 | btCanvas.disabled = true;
25 |
26 | var videoElement = document.getElementById('videoContainer');
27 | document.getElementById('videoview').style.display = 'block';
28 | var overlay = document.getElementById('overlay');
29 | var overlayContext = overlay.getContext('2d');
30 |
31 | var canvas = document.getElementById('pcCanvas');
32 | var ctx = canvas.getContext('2d');
33 |
34 | var count = 1;
35 | var total = 0;
36 |
37 | var decoding_count = 1;
38 | var decoding_total = 0;
39 |
40 | var width, height;
41 |
42 | var isWebGL = false;
43 |
44 | // Initialize canvas
45 | var canvasWebGL = document.createElement('canvas');
46 | var gl = canvasWebGL.getContext("webgl") || canvasWebGL.getContext("experimental-webgl");
47 |
48 | var canvas2d = document.createElement('canvas');
49 | var ctx2d = canvas2d.getContext('2d');
50 |
51 | var gray = null;
52 | var buffer = null;
53 |
54 | function clearOverlay() {
55 | overlayContext.clearRect(0, 0, width, height);
56 | overlayContext.strokeStyle = '#ff0000';
57 | overlayContext.lineWidth = 5;
58 | return overlayContext;
59 | }
60 |
61 | function drawResult(context, localization, text) {
62 | context.beginPath();
63 | context.moveTo(localization.x1, localization.y1);
64 | context.lineTo(localization.x2, localization.y2);
65 | context.lineTo(localization.x3, localization.y3);
66 | context.lineTo(localization.x4, localization.y4);
67 | context.lineTo(localization.x1, localization.y1);
68 | context.stroke();
69 |
70 | context.font = '18px Verdana';
71 | context.fillStyle = '#ff0000';
72 | let x = [localization.x1, localization.x2, localization.x3, localization.x4];
73 | let y = [localization.y1, localization.y2, localization.y3, localization.y4];
74 | x.sort(function (a, b) {
75 | return a - b;
76 | });
77 | y.sort(function (a, b) {
78 | return b - a;
79 | });
80 | let left = x[0];
81 | let top = y[0];
82 |
83 | context.fillText(text, left, top + 50);
84 | }
85 |
86 | function run() {
87 | count = 1;
88 | total = 0;
89 | decoding_count = 1;
90 | decoding_total = 0;
91 | scanBarcode();
92 | }
93 |
94 | btWebGL.onclick = function () {
95 | clearOverlay();
96 | btWebGL.disabled = true;
97 | btCanvas.disabled = false;
98 | isWebGL = true;
99 | run();
100 | };
101 |
102 | btCanvas.onclick = function () {
103 | clearOverlay();
104 | btCanvas.disabled = true;
105 | btWebGL.disabled = false;
106 | isWebGL = false;
107 | run();
108 | };
109 |
110 | // scan barcode
111 | function scanBarcode() {
112 |
113 | // let start = window.performance.now();
114 | let start = Date.now();
115 | let end;
116 |
117 | buffer = new Uint8Array(width * height * 4);
118 |
119 | if (isWebGL) {
120 | gray = new Uint8Array(width * height);
121 |
122 | var drawInfo = {
123 | x: 0,
124 | y: 0,
125 | dx: 1,
126 | dy: 1,
127 | textureInfo: loadImageAndCreateTextureInfo(videoElement)
128 | };
129 |
130 | draw(drawInfo);
131 |
132 | gl.readPixels(
133 | 0,
134 | 0,
135 | gl.drawingBufferWidth,
136 | gl.drawingBufferHeight,
137 | gl.RGBA,
138 | gl.UNSIGNED_BYTE,
139 | buffer
140 | );
141 | // end = window.performance.now();
142 | // end = Date.now();
143 |
144 | // Grayscale image
145 | let gray_index = 0;
146 | for (i = 0; i < width * height * 4; i += 4) {
147 | gray[gray_index++] = buffer[i];
148 | }
149 |
150 | end = Date.now();
151 |
152 | // Draw WebGL texture to canvas
153 | var imgData = ctx.createImageData(width, height);
154 | for (var i = 0; i < buffer.length; i += 4) {
155 | imgData.data[i] = buffer[i]; //red
156 | imgData.data[i + 1] = buffer[i + 1]; //green
157 | imgData.data[i + 2] = buffer[i + 2]; //blue
158 | imgData.data[i + 3] = buffer[i + 3]; //alpha
159 | }
160 | ctx.putImageData(imgData, 0, 0);
161 | }
162 | else {
163 | ctx2d.drawImage(videoElement, 0, 0, width, height);
164 | buffer = ctx2d.getImageData(0, 0, width, height).data;
165 | // end = window.performance.now();
166 | end = Date.now()
167 |
168 | // Draw video frame to canvas
169 | ctx.drawImage(videoElement, 0, 0);
170 | }
171 |
172 | if (isWebGL) {
173 | console.log("%c WebGL buffer time cost: " + (end - start), 'color: green; font-weight: bold;');
174 | }
175 | else
176 | console.log("Canvas buffer time cost: " + (end - start));
177 |
178 | // total += (end - start);
179 | // count += 1;
180 | // if (count == 31) {
181 | // if (isWebGL) {
182 | // console.log("%c WebGL buffer time cost: " + total / 30, 'color: green; font-weight: bold;');
183 | // }
184 | // else
185 | // console.log("Canvas buffer time cost: " + total / 30);
186 | // count = 1;
187 | // total = 0;
188 | // }
189 |
190 | // read barcode
191 | // let decoding_start = window.performance.now();
192 | let decoding_start = Date.now();
193 |
194 | if (isWebGL) {
195 | // console.time("Grayscale Image");
196 | barcodereader
197 | .decodeBuffer(
198 | gray,
199 | width,
200 | height,
201 | width,
202 | Dynamsoft.DBR.EnumImagePixelFormat.IPF_GrayScaled
203 | )
204 | .then((results) => {
205 | // console.timeEnd("Grayscale Image");
206 | if (!isWebGL) return;
207 |
208 | // let decoding_end = window.performance.now();
209 | let decoding_end = Date.now();
210 | console.log("%c Grayscale image Decoding time cost: " + (decoding_end - decoding_start), 'color: green; font-weight: bold;');
211 | console.log("");
212 |
213 | decoding_total += (decoding_end - decoding_start);
214 | decoding_count += 1;
215 | if (decoding_count == 31) {
216 | // console.log("%c Average Decoding time cost: " + decoding_total / 30, 'color: green; font-weight: bold;');
217 | decoding_count = 1;
218 | decoding_total = 0;
219 | }
220 | showResults(results);
221 | });
222 | }
223 | else {
224 | // console.time("Color Image");
225 | barcodereader
226 | .decodeBuffer(
227 | buffer,
228 | width,
229 | height,
230 | width * 4,
231 | Dynamsoft.DBR.EnumImagePixelFormat.IPF_ARGB_8888
232 | )
233 | .then((results) => {
234 | // console.timeEnd("Color Image");
235 | if (isWebGL) return;
236 |
237 | // let decoding_end = window.performance.now();
238 | let decoding_end = Date.now();
239 | console.log("Color image decoding time cost: " + (decoding_end - decoding_start));
240 | console.log("");
241 |
242 | decoding_total += (decoding_end - decoding_start);
243 | decoding_count += 1;
244 | if (decoding_count == 31) {
245 | // console.log("Average Decoding time cost: " + decoding_total / 30);
246 | decoding_count = 1;
247 | decoding_total = 0;
248 | }
249 | showResults(results);
250 | });
251 | }
252 |
253 | }
254 |
255 | console.time('devices');
256 | navigator.mediaDevices.enumerateDevices().then(gotDevices).then(getStream).catch(handleError);
257 |
258 | videoSelect.onchange = getStream;
259 |
260 | function gotDevices(deviceInfos) {
261 | for (var i = deviceInfos.length - 1; i >= 0; --i) {
262 | var deviceInfo = deviceInfos[i];
263 | var option = document.createElement('option');
264 | option.value = deviceInfo.deviceId;
265 | if (deviceInfo.kind === 'videoinput') {
266 | option.text = deviceInfo.label || 'camera ' + (videoSelect.length + 1);
267 | videoSelect.appendChild(option);
268 | } else {
269 | console.log('Found one other kind of source/device: ', deviceInfo);
270 | }
271 | }
272 | }
273 |
274 | function getStream() {
275 | if (window.stream) {
276 | window.stream.getTracks().forEach(function (track) {
277 | track.stop();
278 | });
279 | }
280 |
281 | var constraints = {
282 | video: {
283 | deviceId: videoSelect.value,
284 | width: { min: 640 },
285 | height: { min: 480 },
286 | }
287 | };
288 |
289 | navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(handleError);
290 | }
291 |
292 | function gotStream(stream) {
293 | window.stream = stream;
294 | videoElement.srcObject = stream;
295 | videoElement.addEventListener("loadedmetadata", function (e) {
296 | width = this.videoWidth;
297 | height = this.videoHeight;
298 | console.log(width, height);
299 | canvas.width = width;
300 | canvas.height = height;
301 | canvasWebGL.width = width;
302 | canvasWebGL.height = height;
303 | canvas2d.width = width;
304 | canvas2d.height = height;
305 | overlay.width = width;
306 | overlay.height = height;
307 |
308 | }, false);
309 | }
310 |
311 | function handleError(error) {
312 | console.log('Error: ', error);
313 | }
314 |
315 | function showResults(results) {
316 | let context = clearOverlay();
317 |
318 | let txts = [];
319 | try {
320 | let localization;
321 | if (results.length > 0) {
322 | for (var i = 0; i < results.length; ++i) {
323 | txts.push(results[i].barcodeText);
324 | localization = results[i].localizationResult;
325 | drawResult(context, localization, results[i].barcodeText);
326 | }
327 | barcode_result.textContent = txts.join(', ');
328 | }
329 | else {
330 | barcode_result.textContent = "No barcode found";
331 | }
332 |
333 | scanBarcode();
334 | } catch (e) {
335 | alert(e);
336 | }
337 | }
338 |
339 | /*
340 | * WebGL initialization
341 | * https://webglfundamentals.org/webgl/lessons/webgl-2d-drawimage.html
342 | * https://webglfundamentals.org/webgl/resources/m4.js
343 | * https://webglfundamentals.org/webgl/resources/webgl-utils.js
344 | */
345 |
346 | // setup GLSL program
347 | var program = webglUtils.createProgramFromScripts(gl, ["drawImage-vertex-shader", "drawImage-fragment-shader"]);
348 |
349 | // look up where the vertex data needs to go.
350 | var positionLocation = gl.getAttribLocation(program, "a_position");
351 | var texcoordLocation = gl.getAttribLocation(program, "a_texcoord");
352 |
353 | // lookup uniforms
354 | var matrixLocation = gl.getUniformLocation(program, "u_matrix");
355 | var textureLocation = gl.getUniformLocation(program, "u_texture");
356 |
357 | // Create a buffer.
358 | var positionBuffer = gl.createBuffer();
359 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
360 |
361 | // Put a unit quad in the buffer
362 | var positions = [
363 | 0, 0,
364 | 0, 1,
365 | 1, 0,
366 | 1, 0,
367 | 0, 1,
368 | 1, 1,
369 | ];
370 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
371 |
372 | // Create a buffer for texture coords
373 | var texcoordBuffer = gl.createBuffer();
374 | gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
375 |
376 | // Put texcoords in the buffer
377 | var texcoords = [
378 | 0, 0,
379 | 0, 1,
380 | 1, 0,
381 | 1, 0,
382 | 0, 1,
383 | 1, 1,
384 | ];
385 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW);
386 |
387 | // creates a texture info { width: w, height: h, texture: tex }
388 | // The texture will start with 1x1 pixels and be updated
389 | // when the image has loaded
390 | function loadImageAndCreateTextureInfo(videoElement) {
391 | var tex = gl.createTexture();
392 | var textureInfo = {
393 | width: width,
394 | height: height,
395 | texture: tex,
396 | };
397 |
398 | gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
399 | gl.texImage2D(
400 | gl.TEXTURE_2D,
401 | 0,
402 | gl.RGBA,
403 | gl.RGBA,
404 | gl.UNSIGNED_BYTE,
405 | videoElement
406 | );
407 |
408 | // let's assume all images are not a power of 2
409 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
410 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
411 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
412 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
413 |
414 | return textureInfo;
415 | }
416 |
417 | function draw(drawInfo) {
418 | // webglUtils.resizeCanvasToDisplaySize(gl.canvas);
419 |
420 | // Tell WebGL how to convert from clip space to pixels
421 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
422 |
423 | gl.clear(gl.COLOR_BUFFER_BIT);
424 |
425 | drawImage(
426 | drawInfo.textureInfo.texture,
427 | drawInfo.textureInfo.width,
428 | drawInfo.textureInfo.height,
429 | drawInfo.x,
430 | drawInfo.y);
431 | }
432 |
433 | // Unlike images, textures do not have a width and height associated
434 | // with them so we'll pass in the width and height of the texture
435 | function drawImage(tex, texWidth, texHeight, dstX, dstY) {
436 | gl.bindTexture(gl.TEXTURE_2D, tex);
437 | // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/pixelStorei
438 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
439 |
440 | // Tell WebGL to use our shader program pair
441 | gl.useProgram(program);
442 |
443 | // Setup the attributes to pull data from our buffers
444 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
445 | gl.enableVertexAttribArray(positionLocation);
446 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
447 | gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
448 | gl.enableVertexAttribArray(texcoordLocation);
449 | gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0);
450 |
451 | // this matrix will convert from pixels to clip space
452 | var matrix = m4.orthographic(0, gl.canvas.width, gl.canvas.height, 0, -1, 1);
453 |
454 | // this matrix will translate our quad to dstX, dstY
455 | matrix = m4.translate(matrix, dstX, dstY, 0);
456 |
457 | // this matrix will scale our 1 unit quad
458 | // from 1 unit to texWidth, texHeight units
459 | matrix = m4.scale(matrix, texWidth, texHeight, 1);
460 |
461 | // Set the matrix.
462 | gl.uniformMatrix4fv(matrixLocation, false, matrix);
463 |
464 | // Tell the shader to get the texture from texture unit 0
465 | gl.uniform1i(textureLocation, 0);
466 |
467 | // draw the quad (2 triangles, 6 vertices)
468 | gl.drawArrays(gl.TRIANGLES, 0, 6);
469 | }
--------------------------------------------------------------------------------
/examples/9.x/wrapper-test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft JavaScript Barcode Scanner
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
23 |
24 |
26 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/examples/aadhaar_card/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Results:
9 |
10 |
11 |
12 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/barcode_mrz_document/README.md:
--------------------------------------------------------------------------------
1 | # Scan Barcode, Document and Machine-readable Zone (MRZ) in JavaScript
2 | The sample demonstrates how to use Dynamsoft Capture Vision to scan **1D/2D barcodes**, **document** and **machine-readable zone (MRZ)** within a web browser.
3 |
4 | https://github.com/user-attachments/assets/e205a602-b838-46fa-ac8e-45a009e64ae0
5 |
6 | ## Prerequisites
7 | - Obtain a [30-day free trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform) for Dynamsoft Capture Vision.
8 |
9 | ## Demo
10 | https://yushulx.me/javascript-barcode-qr-code-scanner/examples/barcode_mrz_document
11 |
12 | ## Blog
13 | - [How to Build a Web App to Scan Barcode, Document, and MRZ with JavaScript APIs](https://www.dynamsoft.com/codepool/javascript-scan-barcode-mrz-document.html)
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/barcode_mrz_document/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/barcode_mrz_document/default.png
--------------------------------------------------------------------------------
/examples/barcode_mrz_document/full.json:
--------------------------------------------------------------------------------
1 | {
2 | "CaptureVisionModelOptions": [
3 | {
4 | "ModelArgs": {
5 | "CharSet": {
6 | "ExcludeChars": [
7 | "O",
8 | "Q",
9 | "I"
10 | ]
11 | }
12 | },
13 | "Name": "VINCharRecognition"
14 | },
15 | {
16 | "Name": "MRZCharRecognition",
17 | "DirectoryPath": "",
18 | "MaxModelInstances": 4
19 | },
20 | {
21 | "Name": "MRZTextLineRecognition",
22 | "DirectoryPath": "",
23 | "MaxModelInstances": 1
24 | }
25 | ],
26 | "CaptureVisionTemplates": [
27 | {
28 | "ImageROIProcessingNameArray": [
29 | "roi-read-vin-text"
30 | ],
31 | "Name": "ReadVINText"
32 | },
33 | {
34 | "ImageROIProcessingNameArray": [
35 | "roi-mrz"
36 | ],
37 | "Name": "ReadMRZ",
38 | "SemanticProcessingNameArray": [
39 | "sp-mrz"
40 | ],
41 | "Timeout": 1000000
42 | }
43 | ],
44 | "CodeParserTaskSettingOptions": [
45 | {
46 | "CodeSpecifications": [
47 | "MRTD_TD3_PASSPORT",
48 | "MRTD_TD2_VISA",
49 | "MRTD_TD3_VISA",
50 | "MRTD_TD1_ID",
51 | "MRTD_TD2_ID"
52 | ],
53 | "Name": "dcp-mrz"
54 | }
55 | ],
56 | "ImageParameterOptions": [
57 | {
58 | "ApplicableStages": [
59 | {
60 | "Stage": "SST_INPUT_COLOR_IMAGE"
61 | },
62 | {
63 | "Stage": "SST_SCALE_IMAGE"
64 | },
65 | {
66 | "Stage": "SST_CONVERT_TO_GRAYSCALE"
67 | },
68 | {
69 | "GrayscaleTransformationModes": [
70 | {
71 | "Mode": "GTM_ORIGINAL"
72 | },
73 | {
74 | "Mode": "GTM_INVERTED"
75 | }
76 | ],
77 | "Stage": "SST_TRANSFORM_GRAYSCALE"
78 | },
79 | {
80 | "Stage": "SST_ENHANCE_GRAYSCALE"
81 | },
82 | {
83 | "Stage": "SST_BINARIZE_IMAGE"
84 | },
85 | {
86 | "Stage": "SST_DETECT_TEXTURE"
87 | },
88 | {
89 | "Stage": "SST_REMOVE_TEXTURE_FROM_GRAYSCALE"
90 | },
91 | {
92 | "Stage": "SST_BINARIZE_TEXTURE_REMOVED_GRAYSCALE"
93 | },
94 | {
95 | "Stage": "SST_FIND_CONTOURS"
96 | },
97 | {
98 | "Stage": "SST_DETECT_SHORTLINES"
99 | },
100 | {
101 | "Stage": "SST_ASSEMBLE_LINES"
102 | },
103 | {
104 | "Stage": "SST_DETECT_TEXT_ZONES",
105 | "TextDetectionMode": {
106 | "CharHeightRange": [
107 | 5,
108 | 1000,
109 | 1
110 | ],
111 | "Direction": "HORIZONTAL",
112 | "Mode": "TTDM_LINE",
113 | "Sensitivity": 7
114 | }
115 | },
116 | {
117 | "Stage": "SST_REMOVE_TEXT_ZONES_FROM_BINARY"
118 | }
119 | ],
120 | "Name": "ip_recognize_text"
121 | },
122 | {
123 | "ApplicableStages": [
124 | {
125 | "Stage": "SST_INPUT_COLOR_IMAGE"
126 | },
127 | {
128 | "Stage": "SST_SCALE_IMAGE"
129 | },
130 | {
131 | "Stage": "SST_CONVERT_TO_GRAYSCALE"
132 | },
133 | {
134 | "Stage": "SST_TRANSFORM_GRAYSCALE"
135 | },
136 | {
137 | "Stage": "SST_ENHANCE_GRAYSCALE"
138 | },
139 | {
140 | "BinarizationModes": [
141 | {
142 | "EnableFillBinaryVacancy": 0,
143 | "Mode": "BM_LOCAL_BLOCK",
144 | "ThresholdCompensation": 21
145 | }
146 | ],
147 | "Stage": "SST_BINARIZE_IMAGE"
148 | },
149 | {
150 | "Stage": "SST_DETECT_TEXTURE",
151 | "TextureDetectionModes": [
152 | {
153 | "Mode": "TDM_GENERAL_WIDTH_CONCENTRATION",
154 | "Sensitivity": 8
155 | }
156 | ]
157 | },
158 | {
159 | "Stage": "SST_REMOVE_TEXTURE_FROM_GRAYSCALE"
160 | },
161 | {
162 | "Stage": "SST_BINARIZE_TEXTURE_REMOVED_GRAYSCALE"
163 | },
164 | {
165 | "Stage": "SST_FIND_CONTOURS"
166 | },
167 | {
168 | "Stage": "SST_DETECT_SHORTLINES"
169 | },
170 | {
171 | "Stage": "SST_ASSEMBLE_LINES"
172 | },
173 | {
174 | "Stage": "SST_DETECT_TEXT_ZONES",
175 | "TextDetectionMode": {
176 | "CharHeightRange": [
177 | 5,
178 | 1000,
179 | 1
180 | ],
181 | "Direction": "HORIZONTAL",
182 | "Mode": "TTDM_LINE",
183 | "Sensitivity": 7
184 | }
185 | },
186 | {
187 | "Stage": "SST_REMOVE_TEXT_ZONES_FROM_BINARY"
188 | }
189 | ],
190 | "Name": "ip-mrz"
191 | }
192 | ],
193 | "LabelRecognizerTaskSettingOptions": [
194 | {
195 | "Name": "task-read-vin-text",
196 | "SectionArray": [
197 | {
198 | "ImageParameterName": "ip_recognize_text",
199 | "Section": "ST_REGION_PREDETECTION",
200 | "StageArray": [
201 | {
202 | "Stage": "SST_PREDETECT_REGIONS"
203 | }
204 | ]
205 | },
206 | {
207 | "ImageParameterName": "ip_recognize_text",
208 | "Section": "ST_TEXT_LINE_LOCALIZATION",
209 | "StageArray": [
210 | {
211 | "Stage": "SST_LOCALIZE_TEXT_LINES"
212 | }
213 | ]
214 | },
215 | {
216 | "ImageParameterName": "ip_recognize_text",
217 | "Section": "ST_TEXT_LINE_RECOGNITION",
218 | "StageArray": [
219 | {
220 | "Stage": "SST_RECOGNIZE_RAW_TEXT_LINES"
221 | },
222 | {
223 | "Stage": "SST_ASSEMBLE_TEXT_LINES"
224 | }
225 | ]
226 | }
227 | ],
228 | "TextLineSpecificationNameArray": [
229 | "tls_vin_text"
230 | ]
231 | },
232 | {
233 | "Name": "task-mrz",
234 | "SectionArray": [
235 | {
236 | "ImageParameterName": "ip-mrz",
237 | "Section": "ST_REGION_PREDETECTION",
238 | "StageArray": [
239 | {
240 | "Stage": "SST_PREDETECT_REGIONS"
241 | }
242 | ]
243 | },
244 | {
245 | "ImageParameterName": "ip-mrz",
246 | "Section": "ST_TEXT_LINE_LOCALIZATION",
247 | "StageArray": [
248 | {
249 | "Stage": "SST_LOCALIZE_TEXT_LINES"
250 | }
251 | ]
252 | },
253 | {
254 | "ImageParameterName": "ip-mrz",
255 | "Section": "ST_TEXT_LINE_RECOGNITION",
256 | "StageArray": [
257 | {
258 | "ConfusableCharactersPath": "ConfusableChars.data",
259 | "Stage": "SST_RECOGNIZE_RAW_TEXT_LINES"
260 | },
261 | {
262 | "Stage": "SST_ASSEMBLE_TEXT_LINES"
263 | }
264 | ]
265 | }
266 | ],
267 | "TextLineSpecificationNameArray": [
268 | "tls-mrz-passport",
269 | "tls-mrz-visa-td3",
270 | "tls-mrz-id-td1",
271 | "tls-mrz-id-td2",
272 | "tls-mrz-visa-td2"
273 | ]
274 | }
275 | ],
276 | "SemanticProcessingOptions": [
277 | {
278 | "Name": "sp-mrz",
279 | "ReferenceObjectFilter": {
280 | "ReferenceTargetROIDefNameArray": [
281 | "roi-mrz"
282 | ]
283 | },
284 | "TaskSettingNameArray": [
285 | "dcp-mrz"
286 | ]
287 | }
288 | ],
289 | "TargetROIDefOptions": [
290 | {
291 | "Name": "roi-read-vin-text",
292 | "TaskSettingNameArray": [
293 | "task-read-vin-text"
294 | ]
295 | },
296 | {
297 | "Name": "roi-mrz",
298 | "TaskSettingNameArray": [
299 | "task-mrz"
300 | ]
301 | }
302 | ],
303 | "TextLineSpecificationOptions": [
304 | {
305 | "CharHeightRange": [
306 | 5,
307 | 1000,
308 | 1
309 | ],
310 | "CharacterModelName": "VINCharRecognition",
311 | "ConcatSeparator": "\\n",
312 | "Name": "tls_vin_text",
313 | "StringLengthRange": [
314 | 17,
315 | 17
316 | ],
317 | "StringRegExPattern": "[0-9A-HJ-NPR-Z]{9}[1-9A-HJ-NPR-TV-Y][0-9A-HJ-NPR-Z]{2}[0-9]{5}",
318 | "TextLinesCount": 1
319 | },
320 | {
321 | "BaseTextLineSpecificationName": "tls-base",
322 | "ConcatResults": 1,
323 | "ConcatSeparator": "\\n",
324 | "Name": "tls-mrz-passport",
325 | "StringLengthRange": [
326 | 44,
327 | 44
328 | ],
329 | "SubGroups": [
330 | {
331 | "BaseTextLineSpecificationName": "tls-base",
332 | "StringLengthRange": [
333 | 44,
334 | 44
335 | ],
336 | "StringRegExPattern": "(P[A-Z<][A-Z<]{3}[A-Z<]{39}){(44)}"
337 | },
338 | {
339 | "BaseTextLineSpecificationName": "tls-base",
340 | "StringLengthRange": [
341 | 44,
342 | 44
343 | ],
344 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{14}[0-9<][0-9]){(44)}"
345 | }
346 | ]
347 | },
348 | {
349 | "BaseTextLineSpecificationName": "tls-base",
350 | "ConcatResults": 1,
351 | "ConcatSeparator": "\\n",
352 | "Name": "tls-mrz-visa-td3",
353 | "StringLengthRange": [
354 | 44,
355 | 44
356 | ],
357 | "SubGroups": [
358 | {
359 | "BaseTextLineSpecificationName": "tls-base",
360 | "StringLengthRange": [
361 | 44,
362 | 44
363 | ],
364 | "StringRegExPattern": "(V[A-Z<][A-Z<]{3}[A-Z<]{39}){(44)}"
365 | },
366 | {
367 | "BaseTextLineSpecificationName": "tls-base",
368 | "StringLengthRange": [
369 | 44,
370 | 44
371 | ],
372 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{14}[A-Z0-9<]{2}){(44)}"
373 | }
374 | ]
375 | },
376 | {
377 | "BaseTextLineSpecificationName": "tls-base",
378 | "ConcatResults": 1,
379 | "ConcatSeparator": "\\n",
380 | "Name": "tls-mrz-visa-td2",
381 | "StringLengthRange": [
382 | 36,
383 | 36
384 | ],
385 | "SubGroups": [
386 | {
387 | "BaseTextLineSpecificationName": "tls-base",
388 | "StringLengthRange": [
389 | 36,
390 | 36
391 | ],
392 | "StringRegExPattern": "(V[A-Z<][A-Z<]{3}[A-Z<]{31}){(36)}"
393 | },
394 | {
395 | "BaseTextLineSpecificationName": "tls-base",
396 | "StringLengthRange": [
397 | 36,
398 | 36
399 | ],
400 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{8}){(36)}"
401 | }
402 | ]
403 | },
404 | {
405 | "BaseTextLineSpecificationName": "tls-base",
406 | "ConcatResults": 1,
407 | "ConcatSeparator": "\\n",
408 | "Name": "tls-mrz-id-td2",
409 | "StringLengthRange": [
410 | 36,
411 | 36
412 | ],
413 | "SubGroups": [
414 | {
415 | "BaseTextLineSpecificationName": "tls-base",
416 | "StringLengthRange": [
417 | 36,
418 | 36
419 | ],
420 | "StringRegExPattern": "([ACI][A-Z<][A-Z<]{3}[A-Z<]{31}){(36)}"
421 | },
422 | {
423 | "BaseTextLineSpecificationName": "tls-base",
424 | "StringLengthRange": [
425 | 36,
426 | 36
427 | ],
428 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{8}){(36)}"
429 | }
430 | ]
431 | },
432 | {
433 | "BaseTextLineSpecificationName": "tls-base",
434 | "ConcatResults": 1,
435 | "ConcatSeparator": "\\n",
436 | "Name": "tls-mrz-id-td1",
437 | "StringLengthRange": [
438 | 30,
439 | 30
440 | ],
441 | "SubGroups": [
442 | {
443 | "BaseTextLineSpecificationName": "tls-base",
444 | "StringLengthRange": [
445 | 30,
446 | 30
447 | ],
448 | "StringRegExPattern": "([ACI][A-Z<][A-Z<]{3}[A-Z0-9<]{9}[0-9][A-Z0-9<]{15}){(30)}"
449 | },
450 | {
451 | "BaseTextLineSpecificationName": "tls-base",
452 | "StringLengthRange": [
453 | 30,
454 | 30
455 | ],
456 | "StringRegExPattern": "([0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z<]{3}[A-Z0-9<]{11}[0-9]){(30)}"
457 | },
458 | {
459 | "BaseTextLineSpecificationName": "tls-base",
460 | "StringLengthRange": [
461 | 30,
462 | 30
463 | ],
464 | "StringRegExPattern": "([A-Z<]{30}){(30)}"
465 | }
466 | ]
467 | },
468 | {
469 | "BinarizationModes": [
470 | {
471 | "BlockSizeX": 30,
472 | "BlockSizeY": 30,
473 | "EnableFillBinaryVacancy": 0,
474 | "Mode": "BM_LOCAL_BLOCK",
475 | "ThresholdCompensation": 15
476 | }
477 | ],
478 | "CharHeightRange": [
479 | 5,
480 | 1000,
481 | 1
482 | ],
483 | "CharacterModelName": "MRZCharRecognition",
484 | "TextLineRecModelName": "MRZTextLineRecognition",
485 | "ConfusableCharactersCorrection": {
486 | "ConfusableCharacters": [
487 | [
488 | "0",
489 | "O"
490 | ],
491 | [
492 | "1",
493 | "I"
494 | ],
495 | [
496 | "5",
497 | "S"
498 | ]
499 | ],
500 | "FontNameArray": [
501 | "OCR_B"
502 | ]
503 | },
504 | "Name": "tls-base"
505 | }
506 | ]
507 | }
--------------------------------------------------------------------------------
/examples/barcode_mrz_document/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Dynamsoft Vision SDKs
11 |
12 |
13 |
14 | Scan Barcode, Document and Machine-readable Zone (MRZ)
15 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
41 |
42 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |

69 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
81 |
![]()
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
92 |
93 |
94 |
97 |
98 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |

116 |
117 |
118 |
119 |

120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/examples/barcode_mrz_document/styles.css:
--------------------------------------------------------------------------------
1 | .row {
2 | display: flex;
3 | justify-content: space-between;
4 | margin: 10px auto;
5 | align-items: center;
6 | }
7 |
8 | .container {
9 | max-width: 720px;
10 | margin: 20px auto;
11 | padding: 20px;
12 | border: 1px solid #ddd;
13 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
14 | }
15 |
16 | .loading-indicator {
17 | position: absolute;
18 | top: 0;
19 | left: 0;
20 | width: 100%;
21 | height: 100%;
22 | background-color: rgba(0, 0, 0, 0.5);
23 | z-index: 1000;
24 | display: none;
25 | align-items: center;
26 | justify-content: center;
27 | }
28 |
29 | .spinner {
30 | width: 50px;
31 | height: 50px;
32 | border: 5px solid #fff;
33 | border-radius: 50%;
34 | animation: spin 1s linear infinite;
35 | background: linear-gradient(to right, #FF0000 0%, #FF8000 17%, #FFFF00 33%, #00FF00 50%, #00FFFF 67%, #0080FF 83%, #0000FF 100%);
36 | }
37 |
38 | @keyframes spin {
39 | from {
40 | transform: rotate(0deg);
41 | }
42 |
43 | to {
44 | transform: rotate(360deg);
45 | }
46 | }
47 |
48 | .filler {
49 | flex-grow: 1;
50 | }
51 |
52 | #imageGrid {
53 | width: 720px;
54 | height: 720px;
55 | margin: auto;
56 | display: grid;
57 | grid-template-columns: repeat(2, 1fr);
58 | gap: 50px;
59 | }
60 |
61 | .editor {
62 | display: flex;
63 | margin: 10px auto;
64 | align-items: center;
65 | }
66 |
67 | #videoview {
68 | position: relative;
69 | width: 100%;
70 | height: 40vh;
71 | }
72 |
73 | #videoContainer {
74 | position: relative;
75 | width: 100%;
76 | height: 100%;
77 | z-index: 1
78 | }
79 |
80 | #imageGrid {
81 | width: 720px;
82 | height: 720px;
83 | margin: auto;
84 | display: grid;
85 | grid-template-columns: repeat(2, 1fr);
86 | gap: 50px;
87 | }
88 |
89 | #camera_container {
90 | display: none;
91 | }
92 |
93 | h1 {
94 | text-align: center;
95 | }
96 |
97 | .imageview {
98 | max-width: 720px;
99 | max-height: 720px;
100 | width: 720px;
101 | height: 720px;
102 | border: 1px solid #ddd;
103 | background-color: #eaeaea;
104 | position: relative;
105 | }
106 |
107 | .imageview img {
108 | display: block;
109 | width: 100%;
110 | height: 100%;
111 | object-fit: contain
112 | }
113 |
114 | #sources {
115 | width: 200px;
116 | }
117 |
118 | #dropdown {
119 | width: 200px;
120 | }
121 |
122 | textarea {
123 | width: 680px;
124 | height: 100px;
125 | margin: 10px auto;
126 | padding: 20px;
127 | border: 1px solid #ddd;
128 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
129 | }
130 |
131 | button {
132 | padding: 4px;
133 | margin: 4px;
134 | border: none;
135 | background-color: #007BFF;
136 | color: #fff;
137 | cursor: pointer;
138 | border-radius: 5px;
139 | }
140 |
141 | #drop_area {
142 | border: 2px dashed #ccc;
143 | border-radius: 5px;
144 | padding: 50px;
145 | text-align: center;
146 | margin: 20px;
147 | }
148 |
149 | #drop_area:hover {
150 | background-color: #f8f8f8;
151 | }
152 |
153 | .overlay {
154 | position: absolute;
155 | top: 0;
156 | left: 0;
157 | width: 100%;
158 | height: 100%;
159 | object-fit: contain
160 | }
161 |
162 | #document_editor {
163 | display: none;
164 | }
165 |
166 | #rectify_view {
167 | display: none;
168 | }
169 |
170 | #camera_view {
171 | width: 100%;
172 | height: 100%;
173 | object-fit: contain
174 | }
--------------------------------------------------------------------------------
/examples/barcode_mrz_document/utils.js:
--------------------------------------------------------------------------------
1 | function showMessage(text) {
2 | var messageBox = document.getElementById('message-box');
3 | var messageText = document.getElementById('message-text');
4 | messageText.textContent = text;
5 | messageBox.classList.add('show', 'slide-in');
6 | setTimeout(function () {
7 | messageBox.classList.remove('slide-in');
8 | messageBox.classList.add('slide-out');
9 | setTimeout(function () {
10 | messageBox.classList.remove('show', 'slide-out');
11 | }, 500);
12 | }, 3000);
13 | }
--------------------------------------------------------------------------------
/examples/barcode_ocr_text/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Dynamsoft Capture Vision Example
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
27 |
28 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/examples/barcode_ocr_text/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Arial, sans-serif;
3 | margin: 0 auto;
4 | }
5 |
6 | textarea {
7 | width: 99%;
8 | min-height: 8vh;
9 | font-size: 1em;
10 | overflow: auto;
11 | }
12 |
13 | .loading-indicator {
14 | position: absolute;
15 | top: 0;
16 | left: 0;
17 | width: 100%;
18 | height: 100%;
19 | background-color: rgba(0, 0, 0, 0.5);
20 | z-index: 1000;
21 | display: none;
22 | align-items: center;
23 | justify-content: center;
24 | display: none;
25 | }
26 |
27 | .spinner {
28 | width: 50px;
29 | height: 50px;
30 | border: 5px solid #fff;
31 | border-radius: 50%;
32 | animation: spin 1s linear infinite;
33 | background: linear-gradient(to right, #FF0000 0%, #FF8000 17%, #FFFF00 33%, #00FF00 50%, #00FFFF 67%, #0080FF 83%, #0000FF 100%);
34 | }
35 |
36 | @keyframes spin {
37 | from {
38 | transform: rotate(0deg);
39 | }
40 |
41 | to {
42 | transform: rotate(360deg);
43 | }
44 | }
45 |
46 | .container {
47 | max-width: 640px;
48 | margin: 20px auto;
49 | padding: 20px;
50 | border: 1px solid #ddd;
51 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
52 | display: none;
53 | }
54 |
55 | h1 {
56 | text-align: center;
57 | }
58 |
59 | .connection {
60 | max-width: 640px;
61 | margin: 10px auto;
62 | padding: 20px;
63 | border: 1px solid #ddd;
64 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
65 | }
66 |
67 | input {
68 | width: 300px;
69 | }
70 |
71 | .filler {
72 | flex-grow: 1;
73 | }
--------------------------------------------------------------------------------
/examples/barcode_ocr_text/main.js:
--------------------------------------------------------------------------------
1 | let activateButton = document.getElementById("activate-button");
2 | let loadingIndicator = document.getElementById("loading-indicator");
3 | let container = document.getElementById("container");
4 |
5 | activateButton.onclick = async () => {
6 | loadingIndicator.style.display = "flex";
7 | let inputText = document.getElementById("inputText").value;
8 | let text = inputText.trim();
9 | let placeHolder = document.getElementById("inputText").placeholder;
10 | let license = text.length === 0 ? placeHolder : text;
11 |
12 | try {
13 | Dynamsoft.License.LicenseManager.initLicense(license);
14 | Dynamsoft.Core.CoreModule.loadWasm(["cvr", "dbr", "dlr",]);
15 | await Dynamsoft.CVR.CaptureVisionRouter.appendModelBuffer("LetterCharRecognition");
16 | let router = await Dynamsoft.CVR.CaptureVisionRouter.createInstance();
17 |
18 | let view = await Dynamsoft.DCE.CameraView.createInstance();
19 | let cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(view);
20 |
21 | document.querySelector("#cameraViewContainer").append(view.getUIElement());
22 | router.setInput(cameraEnhancer);
23 |
24 | const resultsContainer = document.querySelector("#results");
25 | const resultReceiver = new Dynamsoft.CVR.CapturedResultReceiver();
26 |
27 | resultReceiver.onCapturedResultReceived = (result) => {
28 | if (result.items.length == 0) {
29 | resultsContainer.textContent = '';
30 | }
31 | }
32 |
33 | resultReceiver.onDecodedBarcodesReceived = (result) => {
34 |
35 | if (result.barcodeResultItems.length > 0) {
36 | for (let item of result.barcodeResultItems) {
37 | resultsContainer.textContent += `Barcode Type: ${item.formatString}, Value: ${item.text}\n\n`;
38 | }
39 | }
40 | }
41 |
42 | resultReceiver.onRecognizedTextLinesReceived = (result) => {
43 |
44 | if (result.textLineResultItems.length > 0) {
45 | for (let item of result.textLineResultItems) {
46 | resultsContainer.textContent += `Text: ${item.text}\n`;
47 | }
48 | }
49 | };
50 | router.addResultReceiver(resultReceiver);
51 |
52 | let filter = new Dynamsoft.Utility.MultiFrameResultCrossFilter();
53 | filter.enableResultCrossVerification(Dynamsoft.Core.EnumCapturedResultItemType.CRIT_BARCODE | Dynamsoft.Core.EnumCapturedResultItemType.CRIT_TEXT_LINE, true);
54 | filter.enableResultDeduplication(Dynamsoft.Core.EnumCapturedResultItemType.CRIT_BARCODE | Dynamsoft.Core.EnumCapturedResultItemType.CRIT_TEXT_LINE, true);
55 | await router.addResultFilter(filter);
56 | await router.initSettings("./template.json");
57 |
58 | await cameraEnhancer.open();
59 | await router.startCapturing("ReadBarcode&AccompanyText");
60 | loadingIndicator.style.display = "none";
61 | container.style.display = "block";
62 | }
63 | catch (ex) {
64 | alert(ex.message);
65 | loadingIndicator.style.display = "none";
66 | }
67 | }
68 |
69 |
70 |
--------------------------------------------------------------------------------
/examples/camera_only/README.md:
--------------------------------------------------------------------------------
1 | ## Accessing Front and Rear Cameras from Web Browsers
2 |
3 | This sample demonstrates how to use [Dynamsoft Camera Enhancer](https://www.dynamsoft.com/camera-enhancer/docs/programming/javascript/user-guide/?ver=latest) to access cameras from web browsers with just a few lines of code.
4 |
5 | 
6 |
7 | ## Online Demo
8 | https://yushulx.me/javascript-barcode-qr-code-scanner/examples/9.x/camera_only
9 |
10 | ## API Reference
11 | https://www.dynamsoft.com/camera-enhancer/docs/programming/javascript/api-reference/?ver=latest
12 |
13 | ## Blog
14 | [How to Implement Camera Access from Web Browsers in 5 Minutes](https://www.dynamsoft.com/codepool/web-browser-javascript-camera-access.html)
15 |
--------------------------------------------------------------------------------
/examples/camera_only/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello Camera
6 |
7 |
8 |
9 |
10 |
11 |
12 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/README.md:
--------------------------------------------------------------------------------
1 | # JavaScript MRZ/VIN Scanner
2 | The sample demonstrates how to use **Dynamsoft Capture Vision** to scan **MRZ (Machine Readable Zone)** and **VIN (Vehicle Identification Number)** within a web browser.
3 |
4 | https://github.com/user-attachments/assets/e536e594-935e-4a31-9e3d-30ca4f929005
5 |
6 | ## Prerequisites
7 | - A valid [Trial License Key](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform) for Dynamsoft Capture Vision.
8 |
9 | ## Online Demo
10 | https://yushulx.me/javascript-barcode-qr-code-scanner/examples/mrz-vin-scanner
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yushulx/javascript-barcode-qr-code-scanner/d11a6439fc2f877b450a15646ece21686c1b8462/examples/mrz-vin-scanner/default.png
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/full.json:
--------------------------------------------------------------------------------
1 | {
2 | "CaptureVisionModelOptions": [
3 | {
4 | "ModelArgs": {
5 | "CharSet": {
6 | "ExcludeChars": [
7 | "O",
8 | "Q",
9 | "I"
10 | ]
11 | }
12 | },
13 | "Name": "VINCharRecognition"
14 | },
15 | {
16 | "Name": "MRZCharRecognition",
17 | "DirectoryPath": "",
18 | "MaxModelInstances": 4
19 | },
20 | {
21 | "Name": "MRZTextLineRecognition",
22 | "DirectoryPath": "",
23 | "MaxModelInstances": 1
24 | }
25 | ],
26 | "CaptureVisionTemplates": [
27 | {
28 | "ImageROIProcessingNameArray": [
29 | "roi-read-vin-text"
30 | ],
31 | "Name": "ReadVINText"
32 | },
33 | {
34 | "ImageROIProcessingNameArray": [
35 | "roi-mrz"
36 | ],
37 | "Name": "ReadMRZ",
38 | "SemanticProcessingNameArray": [
39 | "sp-mrz"
40 | ],
41 | "Timeout": 1000000
42 | }
43 | ],
44 | "CodeParserTaskSettingOptions": [
45 | {
46 | "CodeSpecifications": [
47 | "MRTD_TD3_PASSPORT",
48 | "MRTD_TD2_VISA",
49 | "MRTD_TD3_VISA",
50 | "MRTD_TD1_ID",
51 | "MRTD_TD2_ID"
52 | ],
53 | "Name": "dcp-mrz"
54 | }
55 | ],
56 | "ImageParameterOptions": [
57 | {
58 | "ApplicableStages": [
59 | {
60 | "Stage": "SST_INPUT_COLOR_IMAGE"
61 | },
62 | {
63 | "Stage": "SST_SCALE_IMAGE"
64 | },
65 | {
66 | "Stage": "SST_CONVERT_TO_GRAYSCALE"
67 | },
68 | {
69 | "GrayscaleTransformationModes": [
70 | {
71 | "Mode": "GTM_ORIGINAL"
72 | },
73 | {
74 | "Mode": "GTM_INVERTED"
75 | }
76 | ],
77 | "Stage": "SST_TRANSFORM_GRAYSCALE"
78 | },
79 | {
80 | "Stage": "SST_ENHANCE_GRAYSCALE"
81 | },
82 | {
83 | "Stage": "SST_BINARIZE_IMAGE"
84 | },
85 | {
86 | "Stage": "SST_DETECT_TEXTURE"
87 | },
88 | {
89 | "Stage": "SST_REMOVE_TEXTURE_FROM_GRAYSCALE"
90 | },
91 | {
92 | "Stage": "SST_BINARIZE_TEXTURE_REMOVED_GRAYSCALE"
93 | },
94 | {
95 | "Stage": "SST_FIND_CONTOURS"
96 | },
97 | {
98 | "Stage": "SST_DETECT_SHORTLINES"
99 | },
100 | {
101 | "Stage": "SST_ASSEMBLE_LINES"
102 | },
103 | {
104 | "Stage": "SST_DETECT_TEXT_ZONES",
105 | "TextDetectionMode": {
106 | "CharHeightRange": [
107 | 5,
108 | 1000,
109 | 1
110 | ],
111 | "Direction": "HORIZONTAL",
112 | "Mode": "TTDM_LINE",
113 | "Sensitivity": 7
114 | }
115 | },
116 | {
117 | "Stage": "SST_REMOVE_TEXT_ZONES_FROM_BINARY"
118 | }
119 | ],
120 | "Name": "ip_recognize_text"
121 | },
122 | {
123 | "ApplicableStages": [
124 | {
125 | "Stage": "SST_INPUT_COLOR_IMAGE"
126 | },
127 | {
128 | "Stage": "SST_SCALE_IMAGE"
129 | },
130 | {
131 | "Stage": "SST_CONVERT_TO_GRAYSCALE"
132 | },
133 | {
134 | "Stage": "SST_TRANSFORM_GRAYSCALE"
135 | },
136 | {
137 | "Stage": "SST_ENHANCE_GRAYSCALE"
138 | },
139 | {
140 | "BinarizationModes": [
141 | {
142 | "EnableFillBinaryVacancy": 0,
143 | "Mode": "BM_LOCAL_BLOCK",
144 | "ThresholdCompensation": 21
145 | }
146 | ],
147 | "Stage": "SST_BINARIZE_IMAGE"
148 | },
149 | {
150 | "Stage": "SST_DETECT_TEXTURE",
151 | "TextureDetectionModes": [
152 | {
153 | "Mode": "TDM_GENERAL_WIDTH_CONCENTRATION",
154 | "Sensitivity": 8
155 | }
156 | ]
157 | },
158 | {
159 | "Stage": "SST_REMOVE_TEXTURE_FROM_GRAYSCALE"
160 | },
161 | {
162 | "Stage": "SST_BINARIZE_TEXTURE_REMOVED_GRAYSCALE"
163 | },
164 | {
165 | "Stage": "SST_FIND_CONTOURS"
166 | },
167 | {
168 | "Stage": "SST_DETECT_SHORTLINES"
169 | },
170 | {
171 | "Stage": "SST_ASSEMBLE_LINES"
172 | },
173 | {
174 | "Stage": "SST_DETECT_TEXT_ZONES",
175 | "TextDetectionMode": {
176 | "CharHeightRange": [
177 | 5,
178 | 1000,
179 | 1
180 | ],
181 | "Direction": "HORIZONTAL",
182 | "Mode": "TTDM_LINE",
183 | "Sensitivity": 7
184 | }
185 | },
186 | {
187 | "Stage": "SST_REMOVE_TEXT_ZONES_FROM_BINARY"
188 | }
189 | ],
190 | "Name": "ip-mrz"
191 | }
192 | ],
193 | "LabelRecognizerTaskSettingOptions": [
194 | {
195 | "Name": "task-read-vin-text",
196 | "SectionArray": [
197 | {
198 | "ImageParameterName": "ip_recognize_text",
199 | "Section": "ST_REGION_PREDETECTION",
200 | "StageArray": [
201 | {
202 | "Stage": "SST_PREDETECT_REGIONS"
203 | }
204 | ]
205 | },
206 | {
207 | "ImageParameterName": "ip_recognize_text",
208 | "Section": "ST_TEXT_LINE_LOCALIZATION",
209 | "StageArray": [
210 | {
211 | "Stage": "SST_LOCALIZE_TEXT_LINES"
212 | }
213 | ]
214 | },
215 | {
216 | "ImageParameterName": "ip_recognize_text",
217 | "Section": "ST_TEXT_LINE_RECOGNITION",
218 | "StageArray": [
219 | {
220 | "Stage": "SST_RECOGNIZE_RAW_TEXT_LINES"
221 | },
222 | {
223 | "Stage": "SST_ASSEMBLE_TEXT_LINES"
224 | }
225 | ]
226 | }
227 | ],
228 | "TextLineSpecificationNameArray": [
229 | "tls_vin_text"
230 | ]
231 | },
232 | {
233 | "Name": "task-mrz",
234 | "SectionArray": [
235 | {
236 | "ImageParameterName": "ip-mrz",
237 | "Section": "ST_REGION_PREDETECTION",
238 | "StageArray": [
239 | {
240 | "Stage": "SST_PREDETECT_REGIONS"
241 | }
242 | ]
243 | },
244 | {
245 | "ImageParameterName": "ip-mrz",
246 | "Section": "ST_TEXT_LINE_LOCALIZATION",
247 | "StageArray": [
248 | {
249 | "Stage": "SST_LOCALIZE_TEXT_LINES"
250 | }
251 | ]
252 | },
253 | {
254 | "ImageParameterName": "ip-mrz",
255 | "Section": "ST_TEXT_LINE_RECOGNITION",
256 | "StageArray": [
257 | {
258 | "ConfusableCharactersPath": "ConfusableChars.data",
259 | "Stage": "SST_RECOGNIZE_RAW_TEXT_LINES"
260 | },
261 | {
262 | "Stage": "SST_ASSEMBLE_TEXT_LINES"
263 | }
264 | ]
265 | }
266 | ],
267 | "TextLineSpecificationNameArray": [
268 | "tls-mrz-passport",
269 | "tls-mrz-visa-td3",
270 | "tls-mrz-id-td1",
271 | "tls-mrz-id-td2",
272 | "tls-mrz-visa-td2"
273 | ]
274 | }
275 | ],
276 | "SemanticProcessingOptions": [
277 | {
278 | "Name": "sp-mrz",
279 | "ReferenceObjectFilter": {
280 | "ReferenceTargetROIDefNameArray": [
281 | "roi-mrz"
282 | ]
283 | },
284 | "TaskSettingNameArray": [
285 | "dcp-mrz"
286 | ]
287 | }
288 | ],
289 | "TargetROIDefOptions": [
290 | {
291 | "Name": "roi-read-vin-text",
292 | "TaskSettingNameArray": [
293 | "task-read-vin-text"
294 | ]
295 | },
296 | {
297 | "Name": "roi-mrz",
298 | "TaskSettingNameArray": [
299 | "task-mrz"
300 | ]
301 | }
302 | ],
303 | "TextLineSpecificationOptions": [
304 | {
305 | "CharHeightRange": [
306 | 5,
307 | 1000,
308 | 1
309 | ],
310 | "CharacterModelName": "VINCharRecognition",
311 | "ConcatSeparator": "\\n",
312 | "Name": "tls_vin_text",
313 | "StringLengthRange": [
314 | 17,
315 | 17
316 | ],
317 | "StringRegExPattern": "[0-9A-HJ-NPR-Z]{9}[1-9A-HJ-NPR-TV-Y][0-9A-HJ-NPR-Z]{2}[0-9]{5}",
318 | "TextLinesCount": 1
319 | },
320 | {
321 | "BaseTextLineSpecificationName": "tls-base",
322 | "ConcatResults": 1,
323 | "ConcatSeparator": "\\n",
324 | "Name": "tls-mrz-passport",
325 | "StringLengthRange": [
326 | 44,
327 | 44
328 | ],
329 | "SubGroups": [
330 | {
331 | "BaseTextLineSpecificationName": "tls-base",
332 | "StringLengthRange": [
333 | 44,
334 | 44
335 | ],
336 | "StringRegExPattern": "(P[A-Z<][A-Z<]{3}[A-Z<]{39}){(44)}"
337 | },
338 | {
339 | "BaseTextLineSpecificationName": "tls-base",
340 | "StringLengthRange": [
341 | 44,
342 | 44
343 | ],
344 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{14}[0-9<][0-9]){(44)}"
345 | }
346 | ]
347 | },
348 | {
349 | "BaseTextLineSpecificationName": "tls-base",
350 | "ConcatResults": 1,
351 | "ConcatSeparator": "\\n",
352 | "Name": "tls-mrz-visa-td3",
353 | "StringLengthRange": [
354 | 44,
355 | 44
356 | ],
357 | "SubGroups": [
358 | {
359 | "BaseTextLineSpecificationName": "tls-base",
360 | "StringLengthRange": [
361 | 44,
362 | 44
363 | ],
364 | "StringRegExPattern": "(V[A-Z<][A-Z<]{3}[A-Z<]{39}){(44)}"
365 | },
366 | {
367 | "BaseTextLineSpecificationName": "tls-base",
368 | "StringLengthRange": [
369 | 44,
370 | 44
371 | ],
372 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{14}[A-Z0-9<]{2}){(44)}"
373 | }
374 | ]
375 | },
376 | {
377 | "BaseTextLineSpecificationName": "tls-base",
378 | "ConcatResults": 1,
379 | "ConcatSeparator": "\\n",
380 | "Name": "tls-mrz-visa-td2",
381 | "StringLengthRange": [
382 | 36,
383 | 36
384 | ],
385 | "SubGroups": [
386 | {
387 | "BaseTextLineSpecificationName": "tls-base",
388 | "StringLengthRange": [
389 | 36,
390 | 36
391 | ],
392 | "StringRegExPattern": "(V[A-Z<][A-Z<]{3}[A-Z<]{31}){(36)}"
393 | },
394 | {
395 | "BaseTextLineSpecificationName": "tls-base",
396 | "StringLengthRange": [
397 | 36,
398 | 36
399 | ],
400 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{8}){(36)}"
401 | }
402 | ]
403 | },
404 | {
405 | "BaseTextLineSpecificationName": "tls-base",
406 | "ConcatResults": 1,
407 | "ConcatSeparator": "\\n",
408 | "Name": "tls-mrz-id-td2",
409 | "StringLengthRange": [
410 | 36,
411 | 36
412 | ],
413 | "SubGroups": [
414 | {
415 | "BaseTextLineSpecificationName": "tls-base",
416 | "StringLengthRange": [
417 | 36,
418 | 36
419 | ],
420 | "StringRegExPattern": "([ACI][A-Z<][A-Z<]{3}[A-Z<]{31}){(36)}"
421 | },
422 | {
423 | "BaseTextLineSpecificationName": "tls-base",
424 | "StringLengthRange": [
425 | 36,
426 | 36
427 | ],
428 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{8}){(36)}"
429 | }
430 | ]
431 | },
432 | {
433 | "BaseTextLineSpecificationName": "tls-base",
434 | "ConcatResults": 1,
435 | "ConcatSeparator": "\\n",
436 | "Name": "tls-mrz-id-td1",
437 | "StringLengthRange": [
438 | 30,
439 | 30
440 | ],
441 | "SubGroups": [
442 | {
443 | "BaseTextLineSpecificationName": "tls-base",
444 | "StringLengthRange": [
445 | 30,
446 | 30
447 | ],
448 | "StringRegExPattern": "([ACI][A-Z<][A-Z<]{3}[A-Z0-9<]{9}[0-9][A-Z0-9<]{15}){(30)}"
449 | },
450 | {
451 | "BaseTextLineSpecificationName": "tls-base",
452 | "StringLengthRange": [
453 | 30,
454 | 30
455 | ],
456 | "StringRegExPattern": "([0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z<]{3}[A-Z0-9<]{11}[0-9]){(30)}"
457 | },
458 | {
459 | "BaseTextLineSpecificationName": "tls-base",
460 | "StringLengthRange": [
461 | 30,
462 | 30
463 | ],
464 | "StringRegExPattern": "([A-Z<]{30}){(30)}"
465 | }
466 | ]
467 | },
468 | {
469 | "BinarizationModes": [
470 | {
471 | "BlockSizeX": 30,
472 | "BlockSizeY": 30,
473 | "EnableFillBinaryVacancy": 0,
474 | "Mode": "BM_LOCAL_BLOCK",
475 | "ThresholdCompensation": 15
476 | }
477 | ],
478 | "CharHeightRange": [
479 | 5,
480 | 1000,
481 | 1
482 | ],
483 | "CharacterModelName": "MRZCharRecognition",
484 | "TextLineRecModelName": "MRZTextLineRecognition",
485 | "ConfusableCharactersCorrection": {
486 | "ConfusableCharacters": [
487 | [
488 | "0",
489 | "O"
490 | ],
491 | [
492 | "1",
493 | "I"
494 | ],
495 | [
496 | "5",
497 | "S"
498 | ]
499 | ],
500 | "FontNameArray": [
501 | "OCR_B"
502 | ]
503 | },
504 | "Name": "tls-base"
505 | }
506 | ]
507 | }
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Dynamsoft Capture Vision SDKs
10 |
11 |
12 |
13 | MRZ/VIN Scanner
14 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
40 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |

63 |
64 |
65 |
66 |
67 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
80 |
81 |
84 |
85 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/mrz.json:
--------------------------------------------------------------------------------
1 | {
2 | "CaptureVisionTemplates": [
3 | {
4 | "Name": "ReadMRZ",
5 | "OutputOriginalImage": 0,
6 | "ImageROIProcessingNameArray": [
7 | "roi-mrz"
8 | ],
9 | "SemanticProcessingNameArray": [
10 | "sp-mrz"
11 | ],
12 | "Timeout": 1000000
13 | }
14 | ],
15 | "TargetROIDefOptions": [
16 | {
17 | "Name": "roi-mrz",
18 | "TaskSettingNameArray": [
19 | "task-mrz"
20 | ]
21 | }
22 | ],
23 | "TextLineSpecificationOptions": [
24 | {
25 | "Name": "tls-mrz-passport",
26 | "BaseTextLineSpecificationName": "tls-base",
27 | "StringLengthRange": [
28 | 44,
29 | 44
30 | ],
31 | "OutputResults": 1,
32 | "ExpectedGroupsCount": 1,
33 | "ConcatResults": 1,
34 | "ConcatSeparator": "\\n",
35 | "SubGroups": [
36 | {
37 | "StringRegExPattern": "(P[A-Z<][A-Z<]{3}[A-Z<]{39}){(44)}",
38 | "StringLengthRange": [
39 | 44,
40 | 44
41 | ],
42 | "BaseTextLineSpecificationName": "tls-base"
43 | },
44 | {
45 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{14}[0-9<][0-9]){(44)}",
46 | "StringLengthRange": [
47 | 44,
48 | 44
49 | ],
50 | "BaseTextLineSpecificationName": "tls-base"
51 | }
52 | ]
53 | },
54 | {
55 | "Name": "tls-mrz-visa-td3",
56 | "BaseTextLineSpecificationName": "tls-base",
57 | "StringLengthRange": [
58 | 44,
59 | 44
60 | ],
61 | "OutputResults": 1,
62 | "ExpectedGroupsCount": 1,
63 | "ConcatResults": 1,
64 | "ConcatSeparator": "\\n",
65 | "SubGroups": [
66 | {
67 | "StringRegExPattern": "(V[A-Z<][A-Z<]{3}[A-Z<]{39}){(44)}",
68 | "StringLengthRange": [
69 | 44,
70 | 44
71 | ],
72 | "BaseTextLineSpecificationName": "tls-base"
73 | },
74 | {
75 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{14}[A-Z0-9<]{2}){(44)}",
76 | "StringLengthRange": [
77 | 44,
78 | 44
79 | ],
80 | "BaseTextLineSpecificationName": "tls-base"
81 | }
82 | ]
83 | },
84 | {
85 | "Name": "tls-mrz-visa-td2",
86 | "BaseTextLineSpecificationName": "tls-base",
87 | "StringLengthRange": [
88 | 36,
89 | 36
90 | ],
91 | "OutputResults": 1,
92 | "ExpectedGroupsCount": 1,
93 | "ConcatResults": 1,
94 | "ConcatSeparator": "\\n",
95 | "SubGroups": [
96 | {
97 | "StringRegExPattern": "(V[A-Z<][A-Z<]{3}[A-Z<]{31}){(36)}",
98 | "StringLengthRange": [
99 | 36,
100 | 36
101 | ],
102 | "BaseTextLineSpecificationName": "tls-base"
103 | },
104 | {
105 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{8}){(36)}",
106 | "StringLengthRange": [
107 | 36,
108 | 36
109 | ],
110 | "BaseTextLineSpecificationName": "tls-base"
111 | }
112 | ]
113 | },
114 | {
115 | "Name": "tls-mrz-id-td2",
116 | "BaseTextLineSpecificationName": "tls-base",
117 | "StringLengthRange": [
118 | 36,
119 | 36
120 | ],
121 | "OutputResults": 1,
122 | "ExpectedGroupsCount": 1,
123 | "ConcatResults": 1,
124 | "ConcatSeparator": "\\n",
125 | "SubGroups": [
126 | {
127 | "StringRegExPattern": "([ACI][A-Z<][A-Z<]{3}[A-Z<]{31}){(36)}",
128 | "StringLengthRange": [
129 | 36,
130 | 36
131 | ],
132 | "BaseTextLineSpecificationName": "tls-base"
133 | },
134 | {
135 | "StringRegExPattern": "([A-Z0-9<]{9}[0-9][A-Z<]{3}[0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z0-9<]{8}){(36)}",
136 | "StringLengthRange": [
137 | 36,
138 | 36
139 | ],
140 | "BaseTextLineSpecificationName": "tls-base"
141 | }
142 | ]
143 | },
144 | {
145 | "Name": "tls-mrz-id-td1",
146 | "BaseTextLineSpecificationName": "tls-base",
147 | "StringLengthRange": [
148 | 30,
149 | 30
150 | ],
151 | "OutputResults": 1,
152 | "ExpectedGroupsCount": 1,
153 | "ConcatResults": 1,
154 | "ConcatSeparator": "\\n",
155 | "SubGroups": [
156 | {
157 | "StringRegExPattern": "([ACI][A-Z<][A-Z<]{3}[A-Z0-9<]{9}[0-9][A-Z0-9<]{15}){(30)}",
158 | "StringLengthRange": [
159 | 30,
160 | 30
161 | ],
162 | "BaseTextLineSpecificationName": "tls-base"
163 | },
164 | {
165 | "StringRegExPattern": "([0-9]{2}[(01-12)][(01-31)][0-9][MF<][0-9]{2}[(01-12)][(01-31)][0-9][A-Z<]{3}[A-Z0-9<]{11}[0-9]){(30)}",
166 | "StringLengthRange": [
167 | 30,
168 | 30
169 | ],
170 | "BaseTextLineSpecificationName": "tls-base"
171 | },
172 | {
173 | "StringRegExPattern": "([A-Z<]{30}){(30)}",
174 | "StringLengthRange": [
175 | 30,
176 | 30
177 | ],
178 | "BaseTextLineSpecificationName": "tls-base"
179 | }
180 | ]
181 | },
182 | {
183 | "Name": "tls-base",
184 | "CharacterModelName": "MRZ",
185 | "CharHeightRange": [
186 | 5,
187 | 1000,
188 | 1
189 | ],
190 | "BinarizationModes": [
191 | {
192 | "BlockSizeX": 30,
193 | "BlockSizeY": 30,
194 | "Mode": "BM_LOCAL_BLOCK",
195 | "EnableFillBinaryVacancy": 0,
196 | "ThresholdCompensation": 15
197 | }
198 | ],
199 | "ConfusableCharactersCorrection": {
200 | "ConfusableCharacters": [
201 | [
202 | "0",
203 | "O"
204 | ],
205 | [
206 | "1",
207 | "I"
208 | ],
209 | [
210 | "5",
211 | "S"
212 | ]
213 | ],
214 | "FontNameArray": [
215 | "OCR_B"
216 | ]
217 | }
218 | }
219 | ],
220 | "LabelRecognizerTaskSettingOptions": [
221 | {
222 | "Name": "task-mrz",
223 | "ConfusableCharactersPath": "ConfusableChars.data",
224 | "TextLineSpecificationNameArray": [
225 | "tls-mrz-passport",
226 | "tls-mrz-visa-td3",
227 | "tls-mrz-id-td1",
228 | "tls-mrz-id-td2",
229 | "tls-mrz-visa-td2"
230 | ],
231 | "SectionImageParameterArray": [
232 | {
233 | "Section": "ST_REGION_PREDETECTION",
234 | "ImageParameterName": "ip-mrz"
235 | },
236 | {
237 | "Section": "ST_TEXT_LINE_LOCALIZATION",
238 | "ImageParameterName": "ip-mrz"
239 | },
240 | {
241 | "Section": "ST_TEXT_LINE_RECOGNITION",
242 | "ImageParameterName": "ip-mrz"
243 | }
244 | ]
245 | }
246 | ],
247 | "CharacterModelOptions": [
248 | {
249 | "DirectoryPath": "",
250 | "Name": "MRZ"
251 | }
252 | ],
253 | "ImageParameterOptions": [
254 | {
255 | "Name": "ip-mrz",
256 | "TextureDetectionModes": [
257 | {
258 | "Mode": "TDM_GENERAL_WIDTH_CONCENTRATION",
259 | "Sensitivity": 8
260 | }
261 | ],
262 | "BinarizationModes": [
263 | {
264 | "EnableFillBinaryVacancy": 0,
265 | "ThresholdCompensation": 21,
266 | "Mode": "BM_LOCAL_BLOCK"
267 | }
268 | ],
269 | "TextDetectionMode": {
270 | "Mode": "TTDM_LINE",
271 | "CharHeightRange": [
272 | 5,
273 | 1000,
274 | 1
275 | ],
276 | "Direction": "HORIZONTAL",
277 | "Sensitivity": 7
278 | }
279 | }
280 | ],
281 | "SemanticProcessingOptions": [
282 | {
283 | "Name": "sp-mrz",
284 | "ReferenceObjectFilter": {
285 | "ReferenceTargetROIDefNameArray": [
286 | "roi-mrz"
287 | ]
288 | },
289 | "TaskSettingNameArray": [
290 | "dcp-mrz"
291 | ]
292 | }
293 | ],
294 | "CodeParserTaskSettingOptions": [
295 | {
296 | "Name": "dcp-mrz",
297 | "CodeSpecifications": [
298 | "MRTD_TD3_PASSPORT",
299 | "MRTD_TD2_VISA",
300 | "MRTD_TD3_VISA",
301 | "MRTD_TD1_ID",
302 | "MRTD_TD2_ID"
303 | ]
304 | }
305 | ]
306 | }
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/styles.css:
--------------------------------------------------------------------------------
1 | .row {
2 | display: flex;
3 | justify-content: space-between;
4 | margin: 10px auto;
5 | align-items: center;
6 | }
7 |
8 | .container {
9 | max-width: 720px;
10 | margin: 20px auto;
11 | padding: 20px;
12 | border: 1px solid #ddd;
13 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
14 | }
15 |
16 | .loading-indicator {
17 | position: absolute;
18 | top: 0;
19 | left: 0;
20 | width: 100%;
21 | height: 100%;
22 | background-color: rgba(0, 0, 0, 0.5);
23 | z-index: 1000;
24 | display: none;
25 | align-items: center;
26 | justify-content: center;
27 | }
28 |
29 | .spinner {
30 | width: 50px;
31 | height: 50px;
32 | border: 5px solid #fff;
33 | border-radius: 50%;
34 | animation: spin 1s linear infinite;
35 | background: linear-gradient(to right, #FF0000 0%, #FF8000 17%, #FFFF00 33%, #00FF00 50%, #00FFFF 67%, #0080FF 83%, #0000FF 100%);
36 | }
37 |
38 | @keyframes spin {
39 | from {
40 | transform: rotate(0deg);
41 | }
42 |
43 | to {
44 | transform: rotate(360deg);
45 | }
46 | }
47 |
48 | .filler {
49 | flex-grow: 1;
50 | }
51 |
52 | #imageGrid {
53 | width: 720px;
54 | height: 720px;
55 | margin: auto;
56 | display: grid;
57 | grid-template-columns: repeat(2, 1fr);
58 | gap: 50px;
59 | }
60 |
61 | .editor {
62 | display: flex;
63 | margin: 10px auto;
64 | align-items: center;
65 | }
66 |
67 | #videoview {
68 | position: relative;
69 | width: 100%;
70 | height: 40vh;
71 | }
72 |
73 | #videoContainer {
74 | position: relative;
75 | width: 100%;
76 | height: 100%;
77 | z-index: 1
78 | }
79 |
80 | #imageGrid {
81 | width: 720px;
82 | height: 720px;
83 | margin: auto;
84 | display: grid;
85 | grid-template-columns: repeat(2, 1fr);
86 | gap: 50px;
87 | }
88 |
89 | #camera_container {
90 | display: none;
91 | }
92 |
93 | h1 {
94 | text-align: center;
95 | }
96 |
97 | .imageview {
98 | max-width: 720px;
99 | max-height: 720px;
100 | width: 720px;
101 | height: 720px;
102 | border: 1px solid #ddd;
103 | background-color: #eaeaea;
104 | position: relative;
105 | }
106 |
107 | .imageview img {
108 | display: block;
109 | width: 100%;
110 | height: 100%;
111 | object-fit: contain
112 | }
113 |
114 | #sources {
115 | width: 200px;
116 | }
117 |
118 | #dropdown {
119 | width: 200px;
120 | }
121 |
122 | textarea {
123 | width: 680px;
124 | height: 100px;
125 | margin: 10px auto;
126 | padding: 20px;
127 | border: 1px solid #ddd;
128 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
129 | }
130 |
131 | button {
132 | padding: 4px;
133 | margin: 4px;
134 | border: none;
135 | background-color: #007BFF;
136 | color: #fff;
137 | cursor: pointer;
138 | border-radius: 5px;
139 | }
140 |
141 | #drop_area {
142 | border: 2px dashed #ccc;
143 | border-radius: 5px;
144 | padding: 50px;
145 | text-align: center;
146 | margin: 20px;
147 | }
148 |
149 | #drop_area:hover {
150 | background-color: #f8f8f8;
151 | }
152 |
153 | .overlay {
154 | position: absolute;
155 | top: 0;
156 | left: 0;
157 | width: 100%;
158 | height: 100%;
159 | object-fit: contain
160 | }
161 |
162 | #document_editor {
163 | display: none;
164 | }
165 |
166 | #rectify_view {
167 | display: none;
168 | }
169 |
170 | #camera_view {
171 | width: 100%;
172 | height: 100%;
173 | object-fit: contain
174 | }
--------------------------------------------------------------------------------
/examples/mrz-vin-scanner/vin.json:
--------------------------------------------------------------------------------
1 | {
2 | "CaptureVisionTemplates": [
3 | {
4 | "Name": "ReadVINText",
5 | "ImageROIProcessingNameArray": [
6 | "roi-read-vin-text"
7 | ],
8 | "ImageSource": "",
9 | "MaxParallelTasks": 4,
10 | "MinImageCaptureInterval": 0,
11 | "OutputOriginalImage": 0,
12 | "Timeout": 10000
13 | }
14 | ],
15 | "TargetROIDefOptions": [
16 | {
17 | "Name": "roi-read-vin-text",
18 | "TaskSettingNameArray": [
19 | "task-read-vin-text"
20 | ]
21 | }
22 | ],
23 | "CharacterModelOptions": [
24 | {
25 | "CharSet": {
26 | "ExcludeChars": [
27 | "O",
28 | "Q",
29 | "I"
30 | ]
31 | },
32 | "DirectoryPath": "",
33 | "Name": "VIN"
34 | }
35 | ],
36 | "ImageParameterOptions": [
37 | {
38 | "BaseImageParameterName": "",
39 | "BinarizationModes": [
40 | {
41 | "BinarizationThreshold": -1,
42 | "BlockSizeX": 0,
43 | "BlockSizeY": 0,
44 | "EnableFillBinaryVacancy": 1,
45 | "GrayscaleEnhancementModesIndex": -1,
46 | "Mode": "BM_LOCAL_BLOCK",
47 | "MorphOperation": "Close",
48 | "MorphOperationKernelSizeX": -1,
49 | "MorphOperationKernelSizeY": -1,
50 | "MorphShape": "Rectangle",
51 | "ThresholdCompensation": 10
52 | }
53 | ],
54 | "ColourConversionModes": [
55 | {
56 | "BlueChannelWeight": -1,
57 | "GreenChannelWeight": -1,
58 | "Mode": "CICM_GENERAL",
59 | "RedChannelWeight": -1,
60 | "ReferChannel": "H_CHANNEL"
61 | }
62 | ],
63 | "GrayscaleEnhancementModes": [
64 | {
65 | "Mode": "GEM_GENERAL",
66 | "Sensitivity": -1,
67 | "SharpenBlockSizeX": -1,
68 | "SharpenBlockSizeY": -1,
69 | "SmoothBlockSizeX": -1,
70 | "SmoothBlockSizeY": -1
71 | }
72 | ],
73 | "GrayscaleTransformationModes": [
74 | {
75 | "Mode": "GTM_ORIGINAL"
76 | },
77 | {
78 | "Mode": "GTM_INVERTED"
79 | }
80 | ],
81 | "IfEraseTextZone": 0,
82 | "Name": "ip_recognize_text",
83 | "RegionPredetectionModes": [
84 | {
85 | "AspectRatioRange": "[]",
86 | "FindAccurateBoundary": 0,
87 | "ForeAndBackgroundColours": "[]",
88 | "HeightRange": "[]",
89 | "ImageParameterName": "",
90 | "MeasuredByPercentage": 1,
91 | "MinImageDimension": 262144,
92 | "Mode": "RPM_GENERAL",
93 | "RelativeRegions": "[]",
94 | "Sensitivity": 1,
95 | "SpatialIndexBlockSize": 5,
96 | "WidthRange": "[]"
97 | }
98 | ],
99 | "ScaleDownThreshold": 2300,
100 | "ScaleUpModes": [
101 | {
102 | "AcuteAngleWithXThreshold": -1,
103 | "LetterHeightThreshold": 0,
104 | "Mode": "SUM_AUTO",
105 | "ModuleSizeThreshold": 0,
106 | "TargetLetterHeight": 0,
107 | "TargetModuleSize": 0
108 | }
109 | ],
110 | "TextDetectionMode": {
111 | "CharHeightRange": [
112 | 5,
113 | 1000,
114 | 1
115 | ],
116 | "Direction": "HORIZONTAL",
117 | "MaxSpacingInALine": -1,
118 | "Mode": "TTDM_LINE",
119 | "Sensitivity": 7,
120 | "StringLengthRange": null
121 | },
122 | "TextureDetectionModes": [
123 | {
124 | "Mode": "TDM_GENERAL_WIDTH_CONCENTRATION",
125 | "Sensitivity": 5
126 | }
127 | ]
128 | }
129 | ],
130 | "LabelRecognizerTaskSettingOptions": [
131 | {
132 | "Name": "task-read-vin-text",
133 | "TextLineSpecificationNameArray": [
134 | "tls_vin_text"
135 | ],
136 | "SectionImageParameterArray": [
137 | {
138 | "ContinueWhenPartialResultsGenerated": 1,
139 | "ImageParameterName": "ip_recognize_text",
140 | "Section": "ST_REGION_PREDETECTION"
141 | },
142 | {
143 | "ContinueWhenPartialResultsGenerated": 1,
144 | "ImageParameterName": "ip_recognize_text",
145 | "Section": "ST_TEXT_LINE_LOCALIZATION"
146 | },
147 | {
148 | "ContinueWhenPartialResultsGenerated": 1,
149 | "ImageParameterName": "ip_recognize_text",
150 | "Section": "ST_TEXT_LINE_RECOGNITION"
151 | }
152 | ]
153 | }
154 | ],
155 | "TextLineSpecificationOptions": [
156 | {
157 | "BinarizationModes": [
158 | {
159 | "BinarizationThreshold": -1,
160 | "BlockSizeX": 11,
161 | "BlockSizeY": 11,
162 | "EnableFillBinaryVacancy": 1,
163 | "GrayscaleEnhancementModesIndex": -1,
164 | "Mode": "BM_LOCAL_BLOCK",
165 | "MorphOperation": "Erode",
166 | "MorphOperationKernelSizeX": -1,
167 | "MorphOperationKernelSizeY": -1,
168 | "MorphShape": "Rectangle",
169 | "ThresholdCompensation": 10
170 | }
171 | ],
172 | "CharHeightRange": [
173 | 5,
174 | 1000,
175 | 1
176 | ],
177 | "CharacterModelName": "VIN",
178 | "CharacterNormalizationModes": [
179 | {
180 | "Mode": "CNM_AUTO",
181 | "MorphArgument": "3",
182 | "MorphOperation": "Close"
183 | }
184 | ],
185 | "ConcatResults": 0,
186 | "ConcatSeparator": "\\n",
187 | "ConcatStringLengthRange": [
188 | 3,
189 | 200
190 | ],
191 | "ExpectedGroupsCount": 1,
192 | "GrayscaleEnhancementModes": [
193 | {
194 | "Mode": "GEM_GENERAL",
195 | "Sensitivity": -1,
196 | "SharpenBlockSizeX": -1,
197 | "SharpenBlockSizeY": -1,
198 | "SmoothBlockSizeX": -1,
199 | "SmoothBlockSizeY": -1
200 | }
201 | ],
202 | "Name": "tls_vin_text",
203 | "OutputResults": 1,
204 | "StringLengthRange": [
205 | 17,
206 | 17
207 | ],
208 | "StringRegExPattern": "[0-9A-HJ-NPR-Z]{9}[1-9A-HJ-NPR-TV-Y][0-9A-HJ-NPR-Z]{2}[0-9]{5}",
209 | "SubGroups": null,
210 | "TextLinesCount": 1
211 | }
212 | ]
213 | }
--------------------------------------------------------------------------------
/examples/mrz_scanner_rtu/README.md:
--------------------------------------------------------------------------------
1 | # JavaScript MRZ Scanner – HTML5 & JavaScript Web SDK Example
2 |
3 | This project demonstrates how to create a **web-based Machine Readable Zone (MRZ) scanner** using **HTML5** and **JavaScript**, leveraging the **Dynamsoft MRZ Scanner SDK**. It supports scanning MRZ from **passports**, **ID cards**, and **visa documents** via **camera** or by uploading image and **PDF** files.
4 |
5 | https://github.com/user-attachments/assets/2a7b70e8-8cc6-4563-8925-8a1f7800b093
6 |
7 | ## Prerequisites
8 | - **License Key**: Please obtain a license key from [Dynamsoft Website](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform).
9 | - **Dynamsoft MRZ Scanner**: Read and scan MRZ from passport, ID card, and visa documents.
10 |
11 | ```html
12 |
13 | ```
14 |
15 | - **Dynamsoft Document Viewer**: Convert PDF files to JPEG images in web browser.
16 |
17 | ```html
18 |
19 | ```
20 |
21 | ## Online Demo
22 | https://yushulx.me/javascript-barcode-qr-code-scanner/examples/mrz_scanner_rtu/
23 |
24 | ## Features
25 | - Real-time MRZ scanning using webcam
26 | - Upload and scan MRZ from:
27 | - Image files (PNG, JPEG)
28 | - PDF documents
29 | - Displays parsed MRZ result in structured format
30 |
--------------------------------------------------------------------------------
/examples/mrz_scanner_rtu/helloworld.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft MRZ Scanner - Hello World
8 |
9 |
10 |
11 |
12 | Dynamsoft MRZ Scanner
13 |
14 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/mrz_scanner_rtu/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dynamsoft MRZ Scanner - Hello World
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 | Dynamsoft MRZ Scanner
19 |
20 |
25 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
37 |
38 |
39 |
40 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/examples/mrz_scanner_rtu/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | justify-content: top;
6 | height: 100vh;
7 | margin: 0;
8 | font-family: Arial, sans-serif;
9 | overflow-y: auto;
10 | height: 100%;
11 | }
12 |
13 | .controls {
14 | display: flex;
15 | gap: 10px;
16 | align-items: center;
17 | justify-content: center;
18 | margin-bottom: 20px;
19 | width: 100%;
20 | max-width: 600px;
21 | }
22 |
23 | #scan {
24 | padding: 10px 20px;
25 | font-size: 16px;
26 | flex: 1;
27 | min-width: 120px;
28 | }
29 |
30 | #file {
31 | flex: 1;
32 | min-width: 120px;
33 | padding: 10px;
34 | font-size: 16px;
35 | border: 1px solid #ccc;
36 | background-color: #fff;
37 | cursor: pointer;
38 | }
39 |
40 | #divScanner {
41 | border: 1px solid #ccc;
42 | transition: all 0.3s ease;
43 | }
44 |
45 | #container {
46 | width: 100%;
47 | height: 100%;
48 | }
49 |
50 | #result {
51 | height: 150px;
52 | margin-top: 20px;
53 | border: 1px solid #ccc;
54 | font-size: 14px;
55 | resize: vertical;
56 | }
57 |
58 | .license-row {
59 | display: flex;
60 | flex-direction: row;
61 | align-items: center;
62 | justify-content: center;
63 | gap: 10px;
64 | flex-wrap: wrap;
65 | margin-bottom: 20px;
66 | width: 100%;
67 | max-width: 800px;
68 | text-align: center;
69 | }
70 |
71 | .license-row label {
72 | font-size: 14px;
73 | white-space: nowrap;
74 | }
75 |
76 | .license-row input[type="text"] {
77 | flex: 1;
78 | min-width: 200px;
79 | padding: 8px;
80 | font-size: 14px;
81 | }
82 |
83 | .loading-indicator {
84 | position: absolute;
85 | top: 0;
86 | left: 0;
87 | width: 100%;
88 | height: 100%;
89 | background-color: rgba(0, 0, 0, 0.5);
90 | z-index: 1000;
91 | display: none;
92 | align-items: center;
93 | justify-content: center;
94 | }
95 |
96 | .spinner {
97 | width: 50px;
98 | height: 50px;
99 | border: 5px solid #fff;
100 | border-radius: 50%;
101 | animation: spin 1s linear infinite;
102 | background: linear-gradient(to right, #FF0000 0%, #FF8000 17%, #FFFF00 33%, #00FF00 50%, #00FFFF 67%, #0080FF 83%, #0000FF 100%);
103 | }
104 |
105 | @keyframes spin {
106 | from {
107 | transform: rotate(0deg);
108 | }
109 |
110 | to {
111 | transform: rotate(360deg);
112 | }
113 | }
114 |
115 | #imageContainer {
116 | display: none;
117 | width: 100%;
118 | text-align: center;
119 | margin-top: 20px;
120 | overflow: hidden;
121 | max-height: 40vh;
122 | }
123 |
124 | #imageContainer canvas {
125 | max-width: 100%;
126 | max-height: 40vh;
127 | height: auto;
128 | width: auto;
129 | display: inline-block;
130 | object-fit: contain;
131 | }
--------------------------------------------------------------------------------