import { Barcode } from "./barcode"; import { SearchArea } from "./searchArea"; import { SymbologySettings } from "./symbologySettings"; /** * @hidden */ type SymbologyParameter = Barcode.Symbology | Barcode.Symbology[] | Set; /** * A configuration object for scanning options. * * Modified ScanSettings need to be applied to a scanner via * [[BarcodePicker.applyScanSettings]] or [[Scanner.applyScanSettings]] to take effect. */ export class ScanSettings { private readonly symbologySettings: Map; private readonly properties: Map; private codeDuplicateFilter: number; private maxNumberOfCodesPerFrame: number; private baseSearchArea: SearchArea; private searchArea: SearchArea; private gpuAcceleration: boolean; private blurryRecognition: boolean; /** * Create a ScanSettings instance. * * @param enabledSymbologies
Default = []
* The single symbology or list/set of symbologies that should be initialized as enabled for recognition. * @param codeDuplicateFilter
Default = 0
* The duplicate filter specifying how often a code can be scanned. * When the filter is set to -1, each unique code is only scanned once. When set to 0, * duplicate filtering is disabled. Otherwise the duplicate filter specifies an interval in milliseconds. * When the same code (data/symbology) is scanned within the specified interval it is filtered out as a duplicate. * @param maxNumberOfCodesPerFrame
Default = 1
* The maximum number of barcodes to be recognized every frame. * @param searchArea
Default = { x: 0, y: 0, width: 1.0, height: 1.0 }
* The area of the image in which barcodes are searched. * @param gpuAcceleration
Default = true
* Whether to enable/disable GPU support via WebGL, to provide faster and more accurate barcode localization. * The GPU can and will be used only if the browser also supports the needed technologies * ([WebGL](https://caniuse.com/#feat=webgl) and [OffscreenCanvas](https://caniuse.com/#feat=offscreencanvas)). * @param blurryRecognition
Default = true
* Whether to enable/disable blurry recognition, to allow accurate scanning capabilities for out-of-focus (1D) codes. * If enabled, more advanced algorithms are executed (and more resources/time is spent) every frame in order * to successfully decode/scan difficult codes. */ constructor({ enabledSymbologies = [], codeDuplicateFilter = 0, maxNumberOfCodesPerFrame = 1, searchArea = { x: 0, y: 0, width: 1.0, height: 1.0 }, gpuAcceleration = true, blurryRecognition = true }: { enabledSymbologies?: SymbologyParameter; codeDuplicateFilter?: number; maxNumberOfCodesPerFrame?: number; searchArea?: SearchArea; gpuAcceleration?: boolean; blurryRecognition?: boolean; } = {}) { this.symbologySettings = new Map(); this.enableSymbologies(enabledSymbologies); this.codeDuplicateFilter = codeDuplicateFilter; this.maxNumberOfCodesPerFrame = maxNumberOfCodesPerFrame; this.baseSearchArea = { x: 0, y: 0, width: 1.0, height: 1.0 }; this.searchArea = searchArea; this.gpuAcceleration = gpuAcceleration; this.blurryRecognition = blurryRecognition; this.properties = new Map(); } /** * @returns The configuration object as a JSON string. */ public toJSONString(): string { const symbologies: { [jsonSymbologyName: string]: SymbologySettings } = {}; this.symbologySettings.forEach((symbologySettings, symbology) => { symbologies[Barcode.Symbology.toJSONName(symbology)] = symbologySettings; }); const properties: { [key: string]: number } = {}; this.properties.forEach((value, key) => { properties[key] = value; }); const combinedSearchArea: SearchArea = { x: Math.min(1, this.baseSearchArea.x + this.searchArea.x * this.baseSearchArea.width), y: Math.min(1, this.baseSearchArea.y + this.searchArea.y * this.baseSearchArea.height), width: Math.min(1, this.baseSearchArea.width * this.searchArea.width), height: Math.min(1, this.baseSearchArea.height * this.searchArea.height) }; const isFullSearchArea: boolean = Math.round(combinedSearchArea.x * 100) === 0 && Math.round(combinedSearchArea.y * 100) === 0 && Math.round(combinedSearchArea.width * 100) === 100 && Math.round(combinedSearchArea.height * 100) === 100; return JSON.stringify({ symbologies, codeDuplicateFilter: this.codeDuplicateFilter, maxNumberOfCodesPerFrame: this.maxNumberOfCodesPerFrame, searchArea: combinedSearchArea, codeLocation1d: isFullSearchArea ? undefined : { area: { x: combinedSearchArea.x, y: combinedSearchArea.y + (combinedSearchArea.height * 0.75) / 2, width: combinedSearchArea.width, height: combinedSearchArea.height * 0.25 } }, codeLocation2d: isFullSearchArea ? undefined : { area: combinedSearchArea }, gpuAcceleration: this.gpuAcceleration, blurryRecognition: this.blurryRecognition, properties }); } /** * Get the configuration object for a symbology (which can then be modified). * * @param symbology The symbology for which to retrieve the configuration. * @returns The symbology configuration object for the specified symbology. */ public getSymbologySettings(symbology: Barcode.Symbology): SymbologySettings { if (this.symbologySettings.has(symbology)) { return this.symbologySettings.get(symbology); } else { if (symbology in Barcode.Symbology || Object.values(Barcode.Symbology).includes(symbology)) { this.symbologySettings.set(symbology, new SymbologySettings()); return this.symbologySettings.get(symbology); } else { throw new TypeError(`Invalid symbology "${symbology}"`); } } } /** * Get the recognition enabled status for a symbology. * * @param symbology The symbology for which to retrieve the recognition enabled status. * @returns Whether the symbology enabled for recognition. */ public isSymbologyEnabled(symbology: Barcode.Symbology): boolean { return this.getSymbologySettings(symbology).isEnabled(); } /** * Enable recognition of a symbology or list/set of symbologies. * * @param symbology The single symbology or list/set of symbologies to enable. * @returns The updated [[ScanSettings]] object. */ public enableSymbologies(symbology: SymbologyParameter): ScanSettings { return this.setSymbologiesEnabled(symbology, true); } /** * Disable recognition of a symbology or list/set of symbologies. * * @param symbology The single symbology or list/set of symbologies to disable. * @returns The updated [[ScanSettings]] object. */ public disableSymbologies(symbology: SymbologyParameter): ScanSettings { return this.setSymbologiesEnabled(symbology, false); } /** * When the filter is set to -1, each unique code is only scanned once. When set to 0, * duplicate filtering is disabled. Otherwise the duplicate filter specifies an interval in milliseconds. * * @returns The code duplicate filter value. */ public getCodeDuplicateFilter(): number { return this.codeDuplicateFilter; } /** * Set the code duplicate filter value. * * When the filter is set to -1, each unique code is only scanned once. When set to 0, * duplicate filtering is disabled. Otherwise the duplicate filter specifies an interval in milliseconds. * * @param durationMilliseconds The new value (-1, 0, or positive integer). * @returns The updated [[ScanSettings]] object. */ public setCodeDuplicateFilter(durationMilliseconds: number): ScanSettings { this.codeDuplicateFilter = durationMilliseconds; return this; } /** * @returns The maximum number of barcodes to be recognized every frame. */ public getMaxNumberOfCodesPerFrame(): number { return this.maxNumberOfCodesPerFrame; } /** * Set the maximum number of barcodes to be recognized every frame. * * @param limit The new value (non-zero positive integer). * @returns The updated [[ScanSettings]] object. */ public setMaxNumberOfCodesPerFrame(limit: number): ScanSettings { this.maxNumberOfCodesPerFrame = limit; return this; } /** * @returns The area of the image in which barcodes are searched. */ public getSearchArea(): SearchArea { return this.searchArea; } /** * Set the area of the image in which barcodes are searched. * * @param searchArea The new search area. * @returns The updated [[ScanSettings]] object. */ public setSearchArea(searchArea: SearchArea): ScanSettings { this.searchArea = searchArea; return this; } /** * @hidden * * @returns The base area of the image in which barcodes are searched. */ public getBaseSearchArea(): SearchArea { return this.baseSearchArea; } /** * @hidden * * Set the base area of the image in which barcodes are searched, this is set automatically by a [[BarcodePicker]] * and is combined with the searchArea to obtain the final combined search area. * * @param baseSearchArea The new base search area. * @returns The updated [[ScanSettings]] object. */ public setBaseSearchArea(baseSearchArea: SearchArea): ScanSettings { this.baseSearchArea = baseSearchArea; return this; } /** * @returns Whether GPU acceleration is configured to be enabled ot not. * * Note that this refers to the settings: depending on browser capabilities the actual GPU usage might be prevented. */ public isGpuAccelerationEnabled(): boolean { return this.gpuAcceleration; } /** * Enable or disable GPU acceleration. * * Provide faster and more accurate barcode localization. * The GPU can and will be used only if the browser also supports the needed technologies * ([WebGL](https://caniuse.com/#feat=webgl) and [OffscreenCanvas](https://caniuse.com/#feat=offscreencanvas)). * * @param enabled Whether to enable or disable GPU acceleration. * @returns The updated [[ScanSettings]] object. */ public setGpuAccelerationEnabled(enabled: boolean): ScanSettings { this.gpuAcceleration = enabled; return this; } /** * @returns Whether blurry recognition is configured to be enabled ot not. */ public isBlurryRecognitionEnabled(): boolean { return this.blurryRecognition; } /** * Enable or disable blurry recognition. * * Allow accurate scanning capabilities for out-of-focus (1D) codes. * If enabled, more advanced algorithms are executed (and more resources/time is spent) every frame in order * to successfully decode/scan difficult codes. * * @param enabled Whether to enable or disable blurry recognition. * @returns The updated [[ScanSettings]] object. */ public setBlurryRecognitionEnabled(enabled: boolean): ScanSettings { this.blurryRecognition = enabled; return this; } /** * Get a Scandit Engine library property. * * This function is for internal use only and any functionality that can be accessed through it can and will vanish * without public notice from one version to the next. Do not call this function unless you specifically have to. * * @param key The property name. * @returns The property value. For properties not previously set, -1 is returned. */ public getProperty(key: string): number { if (this.properties.has(key)) { return this.properties.get(key); } return -1; } /** * Set a Scandit Engine library property. * * This function is for internal use only and any functionality that can be accessed through it can and will vanish * without public notice from one version to the next. Do not call this function unless you specifically have to. * * @param key The property name. * @param value The property value. * @returns The updated [[ScanSettings]] object. */ public setProperty(key: string, value: number): ScanSettings { this.properties.set(key, value); return this; } private setSingleSymbologyEnabled(symbology: Barcode.Symbology, enabled: boolean): void { if (symbology in Barcode.Symbology || Object.values(Barcode.Symbology).includes(symbology)) { if (this.symbologySettings.has(symbology)) { (this.symbologySettings.get(symbology)).setEnabled(enabled); } else { this.symbologySettings.set(symbology, new SymbologySettings({ enabled })); } } else { throw new TypeError(`Invalid symbology "${symbology}"`); } } private setMultipleSymbologiesEnabled( symbology: Barcode.Symbology[] | Set, enabled: boolean ): void { for (const s of symbology) { if (!(s in Barcode.Symbology || Object.values(Barcode.Symbology).includes(s))) { throw new TypeError(`Invalid symbology "${s}"`); } } for (const s of symbology) { if (this.symbologySettings.has(s)) { (this.symbologySettings.get(s)).setEnabled(enabled); } else { this.symbologySettings.set(s, new SymbologySettings({ enabled })); } } } private setSymbologiesEnabled(symbology: SymbologyParameter, enabled: boolean): ScanSettings { if (typeof symbology === "object") { this.setMultipleSymbologiesEnabled(symbology, enabled); } else { this.setSingleSymbologyEnabled(symbology, enabled); } return this; } }