UNPKG

14.1 kBPlain TextView Raw
1import { Barcode } from "./barcode";
2import { SearchArea } from "./searchArea";
3import { SymbologySettings } from "./symbologySettings";
4
5/**
6 * @hidden
7 */
8type SymbologyParameter = Barcode.Symbology | Barcode.Symbology[] | Set<Barcode.Symbology>;
9
10/**
11 * A configuration object for scanning options.
12 *
13 * Modified ScanSettings need to be applied to a scanner via
14 * [[BarcodePicker.applyScanSettings]] or [[Scanner.applyScanSettings]] to take effect.
15 */
16export class ScanSettings {
17 private readonly symbologySettings: Map<Barcode.Symbology, SymbologySettings>;
18 private readonly properties: Map<string, number>;
19
20 private codeDuplicateFilter: number;
21 private maxNumberOfCodesPerFrame: number;
22 private baseSearchArea: SearchArea;
23 private searchArea: SearchArea;
24 private gpuAcceleration: boolean;
25 private blurryRecognition: boolean;
26
27 /**
28 * Create a ScanSettings instance.
29 *
30 * @param enabledSymbologies <div class="tsd-signature-symbol">Default =&nbsp;[]</div>
31 * The single symbology or list/set of symbologies that should be initialized as enabled for recognition.
32 * @param codeDuplicateFilter <div class="tsd-signature-symbol">Default =&nbsp;0</div>
33 * The duplicate filter specifying how often a code can be scanned.
34 * When the filter is set to -1, each unique code is only scanned once. When set to 0,
35 * duplicate filtering is disabled. Otherwise the duplicate filter specifies an interval in milliseconds.
36 * When the same code (data/symbology) is scanned within the specified interval it is filtered out as a duplicate.
37 * @param maxNumberOfCodesPerFrame <div class="tsd-signature-symbol">Default =&nbsp;1</div>
38 * The maximum number of barcodes to be recognized every frame.
39 * @param searchArea <div class="tsd-signature-symbol">Default =&nbsp;{ x: 0, y: 0, width: 1.0, height: 1.0 }</div>
40 * The area of the image in which barcodes are searched.
41 * @param gpuAcceleration <div class="tsd-signature-symbol">Default =&nbsp;true</div>
42 * Whether to enable/disable GPU support via WebGL, to provide faster and more accurate barcode localization.
43 * The GPU can and will be used only if the browser also supports the needed technologies
44 * ([WebGL](https://caniuse.com/#feat=webgl) and [OffscreenCanvas](https://caniuse.com/#feat=offscreencanvas)).
45 * @param blurryRecognition <div class="tsd-signature-symbol">Default =&nbsp;true</div>
46 * Whether to enable/disable blurry recognition, to allow accurate scanning capabilities for out-of-focus (1D) codes.
47 * If enabled, more advanced algorithms are executed (and more resources/time is spent) every frame in order
48 * to successfully decode/scan difficult codes.
49 */
50 constructor({
51 enabledSymbologies = [],
52 codeDuplicateFilter = 0,
53 maxNumberOfCodesPerFrame = 1,
54 searchArea = { x: 0, y: 0, width: 1.0, height: 1.0 },
55 gpuAcceleration = true,
56 blurryRecognition = true
57 }: {
58 enabledSymbologies?: SymbologyParameter;
59 codeDuplicateFilter?: number;
60 maxNumberOfCodesPerFrame?: number;
61 searchArea?: SearchArea;
62 gpuAcceleration?: boolean;
63 blurryRecognition?: boolean;
64 } = {}) {
65 this.symbologySettings = new Map<Barcode.Symbology, SymbologySettings>();
66 this.enableSymbologies(enabledSymbologies);
67 this.codeDuplicateFilter = codeDuplicateFilter;
68 this.maxNumberOfCodesPerFrame = maxNumberOfCodesPerFrame;
69 this.baseSearchArea = { x: 0, y: 0, width: 1.0, height: 1.0 };
70 this.searchArea = searchArea;
71 this.gpuAcceleration = gpuAcceleration;
72 this.blurryRecognition = blurryRecognition;
73 this.properties = new Map<string, number>();
74 }
75
76 /**
77 * @returns The configuration object as a JSON string.
78 */
79 public toJSONString(): string {
80 const symbologies: { [jsonSymbologyName: string]: SymbologySettings } = {};
81 this.symbologySettings.forEach((symbologySettings, symbology) => {
82 symbologies[Barcode.Symbology.toJSONName(symbology)] = symbologySettings;
83 });
84 const properties: { [key: string]: number } = {};
85 this.properties.forEach((value, key) => {
86 properties[key] = value;
87 });
88
89 const combinedSearchArea: SearchArea = {
90 x: Math.min(1, this.baseSearchArea.x + this.searchArea.x * this.baseSearchArea.width),
91 y: Math.min(1, this.baseSearchArea.y + this.searchArea.y * this.baseSearchArea.height),
92 width: Math.min(1, this.baseSearchArea.width * this.searchArea.width),
93 height: Math.min(1, this.baseSearchArea.height * this.searchArea.height)
94 };
95
96 const isFullSearchArea: boolean =
97 Math.round(combinedSearchArea.x * 100) === 0 &&
98 Math.round(combinedSearchArea.y * 100) === 0 &&
99 Math.round(combinedSearchArea.width * 100) === 100 &&
100 Math.round(combinedSearchArea.height * 100) === 100;
101
102 return JSON.stringify({
103 symbologies,
104 codeDuplicateFilter: this.codeDuplicateFilter,
105 maxNumberOfCodesPerFrame: this.maxNumberOfCodesPerFrame,
106 searchArea: combinedSearchArea,
107 codeLocation1d: isFullSearchArea
108 ? undefined
109 : {
110 area: {
111 x: combinedSearchArea.x,
112 y: combinedSearchArea.y + (combinedSearchArea.height * 0.75) / 2,
113 width: combinedSearchArea.width,
114 height: combinedSearchArea.height * 0.25
115 }
116 },
117 codeLocation2d: isFullSearchArea
118 ? undefined
119 : {
120 area: combinedSearchArea
121 },
122 gpuAcceleration: this.gpuAcceleration,
123 blurryRecognition: this.blurryRecognition,
124 properties
125 });
126 }
127
128 /**
129 * Get the configuration object for a symbology (which can then be modified).
130 *
131 * @param symbology The symbology for which to retrieve the configuration.
132 * @returns The symbology configuration object for the specified symbology.
133 */
134 public getSymbologySettings(symbology: Barcode.Symbology): SymbologySettings {
135 if (this.symbologySettings.has(symbology)) {
136 return <SymbologySettings>this.symbologySettings.get(symbology);
137 } else {
138 if (symbology in Barcode.Symbology || Object.values(Barcode.Symbology).includes(symbology)) {
139 this.symbologySettings.set(symbology, new SymbologySettings());
140
141 return <SymbologySettings>this.symbologySettings.get(symbology);
142 } else {
143 throw new TypeError(`Invalid symbology "${symbology}"`);
144 }
145 }
146 }
147
148 /**
149 * Get the recognition enabled status for a symbology.
150 *
151 * @param symbology The symbology for which to retrieve the recognition enabled status.
152 * @returns Whether the symbology enabled for recognition.
153 */
154 public isSymbologyEnabled(symbology: Barcode.Symbology): boolean {
155 return this.getSymbologySettings(symbology).isEnabled();
156 }
157
158 /**
159 * Enable recognition of a symbology or list/set of symbologies.
160 *
161 * @param symbology The single symbology or list/set of symbologies to enable.
162 * @returns The updated [[ScanSettings]] object.
163 */
164 public enableSymbologies(symbology: SymbologyParameter): ScanSettings {
165 return this.setSymbologiesEnabled(symbology, true);
166 }
167
168 /**
169 * Disable recognition of a symbology or list/set of symbologies.
170 *
171 * @param symbology The single symbology or list/set of symbologies to disable.
172 * @returns The updated [[ScanSettings]] object.
173 */
174 public disableSymbologies(symbology: SymbologyParameter): ScanSettings {
175 return this.setSymbologiesEnabled(symbology, false);
176 }
177
178 /**
179 * When the filter is set to -1, each unique code is only scanned once. When set to 0,
180 * duplicate filtering is disabled. Otherwise the duplicate filter specifies an interval in milliseconds.
181 *
182 * @returns The code duplicate filter value.
183 */
184 public getCodeDuplicateFilter(): number {
185 return this.codeDuplicateFilter;
186 }
187
188 /**
189 * Set the code duplicate filter value.
190 *
191 * When the filter is set to -1, each unique code is only scanned once. When set to 0,
192 * duplicate filtering is disabled. Otherwise the duplicate filter specifies an interval in milliseconds.
193 *
194 * @param durationMilliseconds The new value (-1, 0, or positive integer).
195 * @returns The updated [[ScanSettings]] object.
196 */
197 public setCodeDuplicateFilter(durationMilliseconds: number): ScanSettings {
198 this.codeDuplicateFilter = durationMilliseconds;
199
200 return this;
201 }
202
203 /**
204 * @returns The maximum number of barcodes to be recognized every frame.
205 */
206 public getMaxNumberOfCodesPerFrame(): number {
207 return this.maxNumberOfCodesPerFrame;
208 }
209
210 /**
211 * Set the maximum number of barcodes to be recognized every frame.
212 *
213 * @param limit The new value (non-zero positive integer).
214 * @returns The updated [[ScanSettings]] object.
215 */
216 public setMaxNumberOfCodesPerFrame(limit: number): ScanSettings {
217 this.maxNumberOfCodesPerFrame = limit;
218
219 return this;
220 }
221
222 /**
223 * @returns The area of the image in which barcodes are searched.
224 */
225 public getSearchArea(): SearchArea {
226 return this.searchArea;
227 }
228
229 /**
230 * Set the area of the image in which barcodes are searched.
231 *
232 * @param searchArea The new search area.
233 * @returns The updated [[ScanSettings]] object.
234 */
235 public setSearchArea(searchArea: SearchArea): ScanSettings {
236 this.searchArea = searchArea;
237
238 return this;
239 }
240
241 /**
242 * @hidden
243 *
244 * @returns The base area of the image in which barcodes are searched.
245 */
246 public getBaseSearchArea(): SearchArea {
247 return this.baseSearchArea;
248 }
249
250 /**
251 * @hidden
252 *
253 * Set the base area of the image in which barcodes are searched, this is set automatically by a [[BarcodePicker]]
254 * and is combined with the searchArea to obtain the final combined search area.
255 *
256 * @param baseSearchArea The new base search area.
257 * @returns The updated [[ScanSettings]] object.
258 */
259 public setBaseSearchArea(baseSearchArea: SearchArea): ScanSettings {
260 this.baseSearchArea = baseSearchArea;
261
262 return this;
263 }
264
265 /**
266 * @returns Whether GPU acceleration is configured to be enabled ot not.
267 *
268 * Note that this refers to the settings: depending on browser capabilities the actual GPU usage might be prevented.
269 */
270 public isGpuAccelerationEnabled(): boolean {
271 return this.gpuAcceleration;
272 }
273
274 /**
275 * Enable or disable GPU acceleration.
276 *
277 * Provide faster and more accurate barcode localization.
278 * The GPU can and will be used only if the browser also supports the needed technologies
279 * ([WebGL](https://caniuse.com/#feat=webgl) and [OffscreenCanvas](https://caniuse.com/#feat=offscreencanvas)).
280 *
281 * @param enabled Whether to enable or disable GPU acceleration.
282 * @returns The updated [[ScanSettings]] object.
283 */
284 public setGpuAccelerationEnabled(enabled: boolean): ScanSettings {
285 this.gpuAcceleration = enabled;
286
287 return this;
288 }
289
290 /**
291 * @returns Whether blurry recognition is configured to be enabled ot not.
292 */
293 public isBlurryRecognitionEnabled(): boolean {
294 return this.blurryRecognition;
295 }
296
297 /**
298 * Enable or disable blurry recognition.
299 *
300 * Allow accurate scanning capabilities for out-of-focus (1D) codes.
301 * If enabled, more advanced algorithms are executed (and more resources/time is spent) every frame in order
302 * to successfully decode/scan difficult codes.
303 *
304 * @param enabled Whether to enable or disable blurry recognition.
305 * @returns The updated [[ScanSettings]] object.
306 */
307 public setBlurryRecognitionEnabled(enabled: boolean): ScanSettings {
308 this.blurryRecognition = enabled;
309
310 return this;
311 }
312
313 /**
314 * Get a Scandit Engine library property.
315 *
316 * This function is for internal use only and any functionality that can be accessed through it can and will vanish
317 * without public notice from one version to the next. Do not call this function unless you specifically have to.
318 *
319 * @param key The property name.
320 * @returns The property value. For properties not previously set, -1 is returned.
321 */
322 public getProperty(key: string): number {
323 if (this.properties.has(key)) {
324 return <number>this.properties.get(key);
325 }
326
327 return -1;
328 }
329
330 /**
331 * Set a Scandit Engine library property.
332 *
333 * This function is for internal use only and any functionality that can be accessed through it can and will vanish
334 * without public notice from one version to the next. Do not call this function unless you specifically have to.
335 *
336 * @param key The property name.
337 * @param value The property value.
338 * @returns The updated [[ScanSettings]] object.
339 */
340 public setProperty(key: string, value: number): ScanSettings {
341 this.properties.set(key, value);
342
343 return this;
344 }
345
346 private setSingleSymbologyEnabled(symbology: Barcode.Symbology, enabled: boolean): void {
347 if (symbology in Barcode.Symbology || Object.values(Barcode.Symbology).includes(symbology)) {
348 if (this.symbologySettings.has(symbology)) {
349 (<SymbologySettings>this.symbologySettings.get(symbology)).setEnabled(enabled);
350 } else {
351 this.symbologySettings.set(symbology, new SymbologySettings({ enabled }));
352 }
353 } else {
354 throw new TypeError(`Invalid symbology "${symbology}"`);
355 }
356 }
357
358 private setMultipleSymbologiesEnabled(
359 symbology: Barcode.Symbology[] | Set<Barcode.Symbology>,
360 enabled: boolean
361 ): void {
362 for (const s of symbology) {
363 if (!(s in Barcode.Symbology || Object.values(Barcode.Symbology).includes(s))) {
364 throw new TypeError(`Invalid symbology "${s}"`);
365 }
366 }
367 for (const s of symbology) {
368 if (this.symbologySettings.has(s)) {
369 (<SymbologySettings>this.symbologySettings.get(s)).setEnabled(enabled);
370 } else {
371 this.symbologySettings.set(s, new SymbologySettings({ enabled }));
372 }
373 }
374 }
375
376 private setSymbologiesEnabled(symbology: SymbologyParameter, enabled: boolean): ScanSettings {
377 if (typeof symbology === "object") {
378 this.setMultipleSymbologiesEnabled(symbology, enabled);
379 } else {
380 this.setSingleSymbologyEnabled(symbology, enabled);
381 }
382
383 return this;
384 }
385}