id-scanner-lib 1.3.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +55 -460
  2. package/dist/id-scanner-lib.esm.js +4641 -0
  3. package/dist/id-scanner-lib.esm.js.map +1 -0
  4. package/dist/id-scanner-lib.js +14755 -0
  5. package/dist/id-scanner-lib.js.map +1 -0
  6. package/dist/types/core/base-module.d.ts +44 -0
  7. package/dist/types/core/camera-manager.d.ts +258 -0
  8. package/dist/types/core/config.d.ts +88 -0
  9. package/dist/types/core/errors.d.ts +111 -0
  10. package/dist/types/core/event-emitter.d.ts +55 -0
  11. package/dist/types/core/logger.d.ts +277 -0
  12. package/dist/types/core/module-manager.d.ts +78 -0
  13. package/dist/types/core/plugin-manager.d.ts +158 -0
  14. package/dist/types/core/resource-manager.d.ts +246 -0
  15. package/dist/types/core/result.d.ts +83 -0
  16. package/dist/types/core/scanner-factory.d.ts +93 -0
  17. package/dist/types/index.bundle.d.ts +1303 -0
  18. package/dist/types/index.d.ts +86 -0
  19. package/dist/types/interfaces/external-types.d.ts +174 -0
  20. package/dist/types/interfaces/face-detection.d.ts +293 -0
  21. package/dist/types/interfaces/scanner-module.d.ts +280 -0
  22. package/dist/types/modules/face/face-detector.d.ts +170 -0
  23. package/dist/types/modules/face/index.d.ts +56 -0
  24. package/dist/types/modules/face/liveness-detector.d.ts +177 -0
  25. package/dist/types/modules/face/types.d.ts +136 -0
  26. package/dist/types/modules/id-card/anti-fake-detector.d.ts +170 -0
  27. package/dist/types/modules/id-card/id-card-detector.d.ts +131 -0
  28. package/dist/types/modules/id-card/index.d.ts +89 -0
  29. package/dist/types/modules/id-card/ocr-processor.d.ts +110 -0
  30. package/dist/types/modules/id-card/ocr-worker.d.ts +31 -0
  31. package/dist/types/modules/id-card/types.d.ts +181 -0
  32. package/dist/types/modules/qrcode/index.d.ts +51 -0
  33. package/dist/types/modules/qrcode/qr-code-scanner.d.ts +64 -0
  34. package/dist/types/modules/qrcode/types.d.ts +67 -0
  35. package/dist/types/utils/camera.d.ts +81 -0
  36. package/dist/types/utils/image-processing.d.ts +176 -0
  37. package/dist/types/utils/index.d.ts +175 -0
  38. package/dist/types/utils/performance.d.ts +81 -0
  39. package/dist/types/utils/resource-manager.d.ts +53 -0
  40. package/dist/types/utils/types.d.ts +166 -0
  41. package/dist/types/utils/worker.d.ts +52 -0
  42. package/dist/types/version.d.ts +7 -0
  43. package/package.json +76 -75
  44. package/src/core/base-module.ts +78 -0
  45. package/src/core/camera-manager.ts +798 -0
  46. package/src/core/config.ts +268 -0
  47. package/src/core/errors.ts +174 -0
  48. package/src/core/event-emitter.ts +110 -0
  49. package/src/core/logger.ts +549 -0
  50. package/src/core/module-manager.ts +165 -0
  51. package/src/core/plugin-manager.ts +429 -0
  52. package/src/core/resource-manager.ts +762 -0
  53. package/src/core/result.ts +163 -0
  54. package/src/core/scanner-factory.ts +237 -0
  55. package/src/index.ts +113 -936
  56. package/src/interfaces/external-types.ts +200 -0
  57. package/src/interfaces/face-detection.ts +309 -0
  58. package/src/interfaces/scanner-module.ts +384 -0
  59. package/src/modules/face/face-detector.ts +931 -0
  60. package/src/modules/face/index.ts +208 -0
  61. package/src/modules/face/liveness-detector.ts +908 -0
  62. package/src/modules/face/types.ts +133 -0
  63. package/src/{id-recognition → modules/id-card}/anti-fake-detector.ts +273 -239
  64. package/src/modules/id-card/id-card-detector.ts +474 -0
  65. package/src/modules/id-card/index.ts +425 -0
  66. package/src/{id-recognition → modules/id-card}/ocr-processor.ts +149 -92
  67. package/src/modules/id-card/ocr-worker.ts +259 -0
  68. package/src/modules/id-card/types.ts +178 -0
  69. package/src/modules/qrcode/index.ts +175 -0
  70. package/src/modules/qrcode/qr-code-scanner.ts +230 -0
  71. package/src/modules/qrcode/types.ts +65 -0
  72. package/src/types/tesseract.d.ts +265 -22
  73. package/src/utils/image-processing.ts +68 -49
  74. package/src/utils/index.ts +426 -0
  75. package/src/utils/performance.ts +168 -131
  76. package/src/utils/resource-manager.ts +65 -146
  77. package/src/utils/types.ts +90 -2
  78. package/src/utils/worker.ts +123 -84
  79. package/src/version.ts +11 -0
  80. package/tools/scaffold.js +543 -0
  81. package/dist/id-scanner-core.esm.js +0 -11349
  82. package/dist/id-scanner-core.js +0 -11361
  83. package/dist/id-scanner-core.min.js +0 -1
  84. package/dist/id-scanner-ocr.esm.js +0 -2319
  85. package/dist/id-scanner-ocr.js +0 -2328
  86. package/dist/id-scanner-ocr.min.js +0 -1
  87. package/dist/id-scanner-qr.esm.js +0 -1296
  88. package/dist/id-scanner-qr.js +0 -1305
  89. package/dist/id-scanner-qr.min.js +0 -1
  90. package/dist/id-scanner.js +0 -4561
  91. package/dist/id-scanner.min.js +0 -1
  92. package/src/core.ts +0 -138
  93. package/src/demo/demo.ts +0 -204
  94. package/src/id-recognition/data-extractor.ts +0 -262
  95. package/src/id-recognition/id-detector.ts +0 -510
  96. package/src/id-recognition/ocr-worker.ts +0 -156
  97. package/src/index-umd.ts +0 -477
  98. package/src/ocr-module.ts +0 -187
  99. package/src/qr-module.ts +0 -179
  100. package/src/scanner/barcode-scanner.ts +0 -251
  101. package/src/scanner/qr-scanner.ts +0 -167
package/src/qr-module.ts DELETED
@@ -1,179 +0,0 @@
1
- /**
2
- * @file 二维码和条形码扫描模块
3
- * @description 包含二维码和条形码扫描功能
4
- * @module IDScannerQR
5
- * @version 1.0.0
6
- * @license MIT
7
- */
8
-
9
- import { QRScanner, QRScannerOptions } from "./scanner/qr-scanner"
10
- import {
11
- BarcodeScanner,
12
- BarcodeScannerOptions,
13
- } from "./scanner/barcode-scanner"
14
- import { Camera, CameraOptions } from "./utils/camera"
15
-
16
- /**
17
- * 扫描模块配置选项
18
- */
19
- export interface ScannerModuleOptions {
20
- cameraOptions?: CameraOptions
21
- qrScannerOptions?: QRScannerOptions
22
- barcodeScannerOptions?: BarcodeScannerOptions
23
- onQRCodeScanned?: (result: string) => void
24
- onBarcodeScanned?: (result: string) => void
25
- onError?: (error: Error) => void
26
- }
27
-
28
- /**
29
- * 扫描模块类
30
- *
31
- * 提供独立的二维码和条形码扫描功能
32
- */
33
- export class ScannerModule {
34
- private qrScanner: QRScanner
35
- private barcodeScanner: BarcodeScanner
36
- private camera: Camera
37
- private scanMode: "qr" | "barcode" | null = null
38
- private videoElement: HTMLVideoElement | null = null
39
-
40
- /**
41
- * 构造函数
42
- * @param options 配置选项
43
- */
44
- constructor(private options: ScannerModuleOptions = {}) {
45
- this.camera = new Camera(options.cameraOptions)
46
- this.qrScanner = new QRScanner({
47
- ...options.qrScannerOptions,
48
- onScan: this.handleQRScan.bind(this),
49
- })
50
- this.barcodeScanner = new BarcodeScanner({
51
- ...options.barcodeScannerOptions,
52
- onScan: this.handleBarcodeScan.bind(this),
53
- })
54
- }
55
-
56
- /**
57
- * 启动二维码扫描
58
- * @param videoElement HTML视频元素
59
- */
60
- async startQRScanner(videoElement: HTMLVideoElement): Promise<void> {
61
- this.stop() // 确保先停止可能正在运行的扫描
62
-
63
- this.videoElement = videoElement
64
- this.scanMode = "qr"
65
- await this.camera.start(videoElement)
66
- this.qrScanner.start(videoElement)
67
- }
68
-
69
- /**
70
- * 启动条形码扫描
71
- * @param videoElement HTML视频元素
72
- */
73
- async startBarcodeScanner(videoElement: HTMLVideoElement): Promise<void> {
74
- this.stop() // 确保先停止可能正在运行的扫描
75
-
76
- this.videoElement = videoElement
77
- this.scanMode = "barcode"
78
- await this.camera.start(videoElement)
79
- this.barcodeScanner.start(videoElement)
80
- }
81
-
82
- /**
83
- * 停止扫描
84
- */
85
- stop(): void {
86
- if (this.scanMode === "qr") {
87
- this.qrScanner.stop()
88
- } else if (this.scanMode === "barcode") {
89
- this.barcodeScanner.stop()
90
- }
91
-
92
- if (this.videoElement) {
93
- this.camera.stop()
94
- }
95
-
96
- this.scanMode = null
97
- }
98
-
99
- /**
100
- * 处理二维码扫描结果
101
- */
102
- private handleQRScan(result: string): void {
103
- if (this.options.onQRCodeScanned) {
104
- this.options.onQRCodeScanned(result)
105
- }
106
- }
107
-
108
- /**
109
- * 处理条形码扫描结果
110
- */
111
- private handleBarcodeScan(result: string): void {
112
- if (this.options.onBarcodeScanned) {
113
- this.options.onBarcodeScanned(result)
114
- }
115
- }
116
-
117
- /**
118
- * 处理错误
119
- */
120
- private handleError(error: Error): void {
121
- if (this.options.onError) {
122
- this.options.onError(error)
123
- } else {
124
- console.error("ScannerModule error:", error)
125
- }
126
- }
127
-
128
- /**
129
- * 处理图像数据中的二维码
130
- * @param imageData 要处理的图像数据
131
- * @returns 返回Promise,解析为扫描结果
132
- */
133
- async processQRCodeImage(imageData: ImageData): Promise<string> {
134
- try {
135
- const result = this.qrScanner.processImageData(imageData)
136
- if (result) {
137
- // 如果需要,触发回调
138
- if (this.options.onQRCodeScanned) {
139
- this.options.onQRCodeScanned(result)
140
- }
141
- return result
142
- }
143
- throw new Error("未检测到二维码")
144
- } catch (error) {
145
- this.handleError(error as Error)
146
- throw error
147
- }
148
- }
149
-
150
- /**
151
- * 处理图像数据中的条形码
152
- * @param imageData 要处理的图像数据
153
- * @returns 返回Promise,解析为扫描结果
154
- */
155
- async processBarcodeImage(imageData: ImageData): Promise<string> {
156
- try {
157
- const result = this.barcodeScanner.processImageData(imageData)
158
- if (result) {
159
- // 如果需要,触发回调
160
- if (this.options.onBarcodeScanned) {
161
- this.options.onBarcodeScanned(result)
162
- }
163
- return result
164
- }
165
- throw new Error("未检测到条形码")
166
- } catch (error) {
167
- this.handleError(error as Error)
168
- throw error
169
- }
170
- }
171
- }
172
-
173
- // 导出相关类型和工具
174
- export { QRScanner, QRScannerOptions } from "./scanner/qr-scanner"
175
- export {
176
- BarcodeScanner,
177
- BarcodeScannerOptions,
178
- } from "./scanner/barcode-scanner"
179
- export { Camera, CameraOptions } from "./utils/camera"
@@ -1,251 +0,0 @@
1
- /**
2
- * @file 条形码扫描模块
3
- * @description 提供实时条形码扫描和识别功能
4
- * @module BarcodeScanner
5
- */
6
-
7
- import { Camera } from "../utils/camera"
8
- import { ImageProcessor } from "../utils/image-processing"
9
-
10
- /**
11
- * 条形码扫描器配置选项
12
- *
13
- * @interface BarcodeScannerOptions
14
- * @property {number} [scanInterval] - 扫描间隔时间(毫秒),默认为200ms
15
- * @property {Function} [onScan] - 扫描成功回调函数
16
- * @property {Function} [onError] - 错误处理回调函数
17
- */
18
- export interface BarcodeScannerOptions {
19
- scanInterval?: number
20
- onScan?: (result: string) => void
21
- onError?: (error: Error) => void
22
- }
23
-
24
- /**
25
- * 条形码扫描器类
26
- *
27
- * 提供实时扫描和识别摄像头中的条形码的功能
28
- * 注意:当前实现是简化版,实际项目中建议集成专门的条形码识别库如ZXing或Quagga.js
29
- *
30
- * @example
31
- * ```typescript
32
- * // 创建条形码扫描器
33
- * const barcodeScanner = new BarcodeScanner({
34
- * scanInterval: 100, // 每100ms扫描一次
35
- * onScan: (result) => {
36
- * console.log('扫描到条形码:', result);
37
- * },
38
- * onError: (error) => {
39
- * console.error('扫描错误:', error);
40
- * }
41
- * });
42
- *
43
- * // 启动扫描
44
- * const videoElement = document.getElementById('video') as HTMLVideoElement;
45
- * await barcodeScanner.start(videoElement);
46
- *
47
- * // 停止扫描
48
- * barcodeScanner.stop();
49
- * ```
50
- */
51
- export class BarcodeScanner {
52
- private camera: Camera
53
- private scanning = false
54
- private scanTimer: number | null = null
55
-
56
- /**
57
- * 创建条形码扫描器实例
58
- *
59
- * @param {BarcodeScannerOptions} [options] - 扫描器配置选项
60
- */
61
- constructor(private options: BarcodeScannerOptions = {}) {
62
- this.options = {
63
- scanInterval: 200,
64
- ...options,
65
- }
66
-
67
- this.camera = new Camera()
68
- }
69
-
70
- /**
71
- * 启动条形码扫描
72
- *
73
- * 初始化相机并开始连续扫描视频帧中的条形码
74
- *
75
- * @param {HTMLVideoElement} videoElement - 用于显示相机画面的video元素
76
- * @returns {Promise<void>} 启动完成的Promise
77
- * @throws 如果无法访问相机,将通过onError回调报告错误
78
- */
79
- async start(videoElement: HTMLVideoElement): Promise<void> {
80
- try {
81
- await this.camera.initialize(videoElement)
82
- this.scanning = true
83
- this.scan()
84
- } catch (error) {
85
- if (this.options.onError) {
86
- this.options.onError(
87
- error instanceof Error ? error : new Error(String(error))
88
- )
89
- }
90
- }
91
- }
92
-
93
- /**
94
- * 执行一次条形码扫描
95
- *
96
- * 内部方法,捕获当前视频帧并尝试识别其中的条形码
97
- *
98
- * @private
99
- */
100
- private scan(): void {
101
- if (!this.scanning) return
102
-
103
- const imageData = this.camera.captureFrame()
104
-
105
- if (imageData) {
106
- try {
107
- // 图像预处理,提高识别率
108
- const enhancedImage = ImageProcessor.adjustBrightnessContrast(
109
- ImageProcessor.toGrayscale(imageData),
110
- 10, // 亮度
111
- 20 // 对比度
112
- )
113
-
114
- // 这里实际项目中可以集成第三方条形码扫描库
115
- // 如 ZXing 或 QuaggaJS
116
- // 简化实现,这里仅为示例
117
- this.detectBarcode(enhancedImage)
118
- } catch (error) {
119
- console.error("条形码扫描错误:", error)
120
- }
121
- }
122
-
123
- this.scanTimer = window.setTimeout(
124
- () => this.scan(),
125
- this.options.scanInterval
126
- )
127
- }
128
-
129
- /**
130
- * 条形码检测方法
131
- *
132
- * 注意:这是一个简化实现,实际需要集成专门的条形码识别库
133
- *
134
- * @private
135
- * @param {ImageData} imageData - 要检测条形码的图像数据
136
- */
137
- private detectBarcode(imageData: ImageData): void {
138
- // 这里应集成条形码识别库
139
- // 如 ZXing 或 QuaggaJS
140
-
141
- // 简化示例,实际项目中请替换为真实实现
142
- console.log("正在扫描条形码...")
143
-
144
- // 模拟找到条形码
145
- if (Math.random() > 0.95) {
146
- const mockResult = "6901234567890" // 模拟条形码结果
147
-
148
- if (this.options.onScan) {
149
- this.options.onScan(mockResult)
150
- }
151
- }
152
- }
153
-
154
- /**
155
- * 停止条形码扫描
156
- *
157
- * 停止扫描循环并释放相机资源
158
- */
159
- stop(): void {
160
- this.scanning = false
161
-
162
- if (this.scanTimer) {
163
- clearTimeout(this.scanTimer)
164
- this.scanTimer = null
165
- }
166
-
167
- this.camera.release()
168
- }
169
-
170
- /**
171
- * 处理图像数据中的条形码
172
- *
173
- * @param {ImageData} imageData - 要处理的图像数据
174
- * @returns {string | null} 识别到的条形码内容,如未识别到则返回null
175
- */
176
- processImageData(imageData: ImageData): string | null {
177
- try {
178
- if (
179
- !imageData ||
180
- !imageData.data ||
181
- imageData.width <= 0 ||
182
- imageData.height <= 0
183
- ) {
184
- throw new Error("无效的图像数据")
185
- }
186
-
187
- // 图像预处理,提高识别率
188
- const enhancedImage = ImageProcessor.adjustBrightnessContrast(
189
- ImageProcessor.toGrayscale(imageData),
190
- 10, // 亮度
191
- 20 // 对比度
192
- )
193
-
194
- // 注意:这里是简化实现
195
- // 实际项目中,应该集成专门的条形码识别库如ZXing或Quagga.js
196
-
197
- // 模拟条形码识别
198
- // 在真实项目中,请替换为实际的条形码识别算法
199
- const result = this.simulateBarcodeDetection(enhancedImage)
200
- return result
201
- } catch (error) {
202
- if (this.options.onError) {
203
- this.options.onError(
204
- error instanceof Error ? error : new Error(String(error))
205
- )
206
- }
207
- return null
208
- }
209
- }
210
-
211
- /**
212
- * 模拟条形码检测
213
- * 仅用于演示,实际使用时应该替换为真实的条形码识别算法
214
- *
215
- * @private
216
- * @param {ImageData} imageData - 要检测条形码的图像数据
217
- * @returns {string | null} 模拟的条形码识别结果
218
- */
219
- private simulateBarcodeDetection(imageData: ImageData): string | null {
220
- // 这里只是模拟,真实环境中应当使用条形码识别库进行识别
221
-
222
- // 在中间区域检测到足够多垂直边缘时,认为可能存在条形码
223
- const midX = Math.floor(imageData.width / 2)
224
- const midY = Math.floor(imageData.height / 2)
225
- const sampleWidth = Math.min(100, Math.floor(imageData.width / 3))
226
-
227
- let edgeCount = 0
228
- let lastPixel = 0
229
-
230
- // 简单的边缘检测,统计中心水平线上像素变化次数
231
- for (let x = midX - sampleWidth / 2; x < midX + sampleWidth / 2; x++) {
232
- const pixelPos = (midY * imageData.width + x) * 4
233
- const pixelValue = imageData.data[pixelPos]
234
-
235
- if (Math.abs(pixelValue - lastPixel) > 30) {
236
- edgeCount++
237
- }
238
-
239
- lastPixel = pixelValue
240
- }
241
-
242
- // 如果边缘变化次数在合理范围内,认为是条形码
243
- // 实际的条形码具有规律的宽窄条纹
244
- if (edgeCount > 10 && edgeCount < 50) {
245
- // 生成一个模拟的条形码结果
246
- return "690" + Math.floor(Math.random() * 10000000000)
247
- }
248
-
249
- return null
250
- }
251
- }
@@ -1,167 +0,0 @@
1
- /**
2
- * @file 二维码扫描模块
3
- * @description 提供实时二维码扫描和识别功能
4
- * @module QRScanner
5
- */
6
-
7
- import jsQR from "jsqr"
8
- import { Camera } from "../utils/camera"
9
-
10
- /**
11
- * 二维码扫描器配置选项
12
- *
13
- * @interface QRScannerOptions
14
- * @property {number} [scanInterval] - 扫描间隔时间(毫秒),默认为200ms
15
- * @property {Function} [onScan] - 扫描成功回调函数
16
- * @property {Function} [onError] - 错误处理回调函数
17
- */
18
- export interface QRScannerOptions {
19
- scanInterval?: number
20
- onScan?: (result: string) => void
21
- onError?: (error: Error) => void
22
- }
23
-
24
- /**
25
- * 二维码扫描器类
26
- *
27
- * 提供实时扫描和识别摄像头中的二维码的功能
28
- *
29
- * @example
30
- * ```typescript
31
- * // 创建二维码扫描器
32
- * const qrScanner = new QRScanner({
33
- * scanInterval: 100, // 每100ms扫描一次
34
- * onScan: (result) => {
35
- * console.log('扫描到二维码:', result);
36
- * },
37
- * onError: (error) => {
38
- * console.error('扫描错误:', error);
39
- * }
40
- * });
41
- *
42
- * // 启动扫描
43
- * const videoElement = document.getElementById('video') as HTMLVideoElement;
44
- * await qrScanner.start(videoElement);
45
- *
46
- * // 停止扫描
47
- * qrScanner.stop();
48
- * ```
49
- */
50
- export class QRScanner {
51
- private camera: Camera
52
- private scanning = false
53
- private scanTimer: number | null = null
54
-
55
- /**
56
- * 创建二维码扫描器实例
57
- *
58
- * @param {QRScannerOptions} [options] - 扫描器配置选项
59
- */
60
- constructor(private options: QRScannerOptions = {}) {
61
- this.options = {
62
- scanInterval: 200,
63
- ...options,
64
- }
65
-
66
- this.camera = new Camera()
67
- }
68
-
69
- /**
70
- * 启动二维码扫描
71
- *
72
- * 初始化相机并开始连续扫描视频帧中的二维码
73
- *
74
- * @param {HTMLVideoElement} videoElement - 用于显示相机画面的video元素
75
- * @returns {Promise<void>} 启动完成的Promise
76
- * @throws 如果无法访问相机,将通过onError回调报告错误
77
- */
78
- async start(videoElement: HTMLVideoElement): Promise<void> {
79
- try {
80
- await this.camera.initialize(videoElement)
81
- this.scanning = true
82
- this.scan()
83
- } catch (error) {
84
- if (this.options.onError) {
85
- this.options.onError(
86
- error instanceof Error ? error : new Error(String(error))
87
- )
88
- }
89
- }
90
- }
91
-
92
- /**
93
- * 执行一次二维码扫描
94
- *
95
- * 内部方法,捕获当前视频帧并尝试识别其中的二维码
96
- *
97
- * @private
98
- */
99
- private scan(): void {
100
- if (!this.scanning) return
101
-
102
- const imageData = this.camera.captureFrame()
103
-
104
- if (imageData) {
105
- const code = jsQR(imageData.data, imageData.width, imageData.height)
106
-
107
- if (code && this.options.onScan) {
108
- this.options.onScan(code.data)
109
- }
110
- }
111
-
112
- this.scanTimer = window.setTimeout(
113
- () => this.scan(),
114
- this.options.scanInterval
115
- )
116
- }
117
-
118
- /**
119
- * 停止二维码扫描
120
- *
121
- * 停止扫描循环并释放相机资源
122
- */
123
- stop(): void {
124
- this.scanning = false
125
-
126
- if (this.scanTimer) {
127
- clearTimeout(this.scanTimer)
128
- this.scanTimer = null
129
- }
130
-
131
- this.camera.release()
132
- }
133
-
134
- /**
135
- * 处理图像数据中的二维码
136
- *
137
- * @param {ImageData} imageData - 要处理的图像数据
138
- * @returns {string | null} 识别到的二维码内容,如未识别到则返回null
139
- */
140
- processImageData(imageData: ImageData): string | null {
141
- try {
142
- if (
143
- !imageData ||
144
- !imageData.data ||
145
- imageData.width <= 0 ||
146
- imageData.height <= 0
147
- ) {
148
- throw new Error("无效的图像数据")
149
- }
150
-
151
- const code = jsQR(imageData.data, imageData.width, imageData.height)
152
-
153
- if (code && code.data) {
154
- return code.data
155
- }
156
-
157
- return null
158
- } catch (error) {
159
- if (this.options.onError) {
160
- this.options.onError(
161
- error instanceof Error ? error : new Error(String(error))
162
- )
163
- }
164
- return null
165
- }
166
- }
167
- }