id-scanner-lib 1.2.2 → 1.3.2

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 (67) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +375 -363
  3. package/dist/id-scanner-core.esm.js +427 -221
  4. package/dist/id-scanner-core.esm.js.map +1 -1
  5. package/dist/id-scanner-core.js +427 -221
  6. package/dist/id-scanner-core.js.map +1 -1
  7. package/dist/id-scanner-core.min.js +1 -9
  8. package/dist/id-scanner-core.min.js.map +1 -1
  9. package/dist/id-scanner-ocr.esm.js +451 -276
  10. package/dist/id-scanner-ocr.esm.js.map +1 -1
  11. package/dist/id-scanner-ocr.js +451 -276
  12. package/dist/id-scanner-ocr.js.map +1 -1
  13. package/dist/id-scanner-ocr.min.js +1 -9
  14. package/dist/id-scanner-ocr.min.js.map +1 -1
  15. package/dist/id-scanner-qr.esm.js +483 -233
  16. package/dist/id-scanner-qr.esm.js.map +1 -1
  17. package/dist/id-scanner-qr.js +482 -232
  18. package/dist/id-scanner-qr.js.map +1 -1
  19. package/dist/id-scanner-qr.min.js +1 -9
  20. package/dist/id-scanner-qr.min.js.map +1 -1
  21. package/dist/id-scanner.js +2138 -358
  22. package/dist/id-scanner.js.map +1 -1
  23. package/dist/id-scanner.min.js +1 -9
  24. package/dist/id-scanner.min.js.map +1 -1
  25. package/package.json +27 -7
  26. package/src/demo/demo.ts +178 -62
  27. package/src/id-recognition/anti-fake-detector.ts +317 -0
  28. package/src/id-recognition/id-detector.ts +184 -155
  29. package/src/id-recognition/ocr-processor.ts +193 -146
  30. package/src/id-recognition/ocr-worker.ts +82 -72
  31. package/src/index-umd.ts +347 -110
  32. package/src/index.ts +866 -91
  33. package/src/ocr-module.ts +108 -60
  34. package/src/qr-module.ts +104 -54
  35. package/src/scanner/barcode-scanner.ts +145 -58
  36. package/src/scanner/qr-scanner.ts +86 -47
  37. package/src/utils/image-processing.ts +479 -294
  38. package/dist/core.d.ts +0 -77
  39. package/dist/demo/demo.d.ts +0 -14
  40. package/dist/id-recognition/data-extractor.d.ts +0 -105
  41. package/dist/id-recognition/id-detector.d.ts +0 -100
  42. package/dist/id-recognition/ocr-processor.d.ts +0 -64
  43. package/dist/id-scanner.esm.js +0 -94656
  44. package/dist/id-scanner.esm.js.map +0 -1
  45. package/dist/index-umd.d.ts +0 -96
  46. package/dist/index.d.ts +0 -78
  47. package/dist/ocr-module.d.ts +0 -67
  48. package/dist/qr-module.d.ts +0 -68
  49. package/dist/scanner/barcode-scanner.d.ts +0 -90
  50. package/dist/scanner/qr-scanner.d.ts +0 -80
  51. package/dist/types/core.d.ts +0 -77
  52. package/dist/types/demo/demo.d.ts +0 -14
  53. package/dist/types/id-recognition/data-extractor.d.ts +0 -105
  54. package/dist/types/id-recognition/id-detector.d.ts +0 -100
  55. package/dist/types/id-recognition/ocr-processor.d.ts +0 -64
  56. package/dist/types/index-umd.d.ts +0 -96
  57. package/dist/types/index.d.ts +0 -78
  58. package/dist/types/ocr-module.d.ts +0 -67
  59. package/dist/types/qr-module.d.ts +0 -68
  60. package/dist/types/scanner/barcode-scanner.d.ts +0 -90
  61. package/dist/types/scanner/qr-scanner.d.ts +0 -80
  62. package/dist/types/utils/camera.d.ts +0 -81
  63. package/dist/types/utils/image-processing.d.ts +0 -75
  64. package/dist/types/utils/types.d.ts +0 -65
  65. package/dist/utils/camera.d.ts +0 -81
  66. package/dist/utils/image-processing.d.ts +0 -75
  67. package/dist/utils/types.d.ts +0 -65
package/src/index-umd.ts CHANGED
@@ -6,30 +6,35 @@
6
6
  * @license MIT
7
7
  */
8
8
 
9
- import { Camera, CameraOptions } from './utils/camera';
10
- import { IDCardInfo, DetectionResult } from './utils/types';
11
- import type { QRScannerOptions } from './scanner/qr-scanner';
12
- import type { BarcodeScannerOptions } from './scanner/barcode-scanner';
9
+ import { Camera, CameraOptions } from "./utils/camera"
10
+ import { IDCardInfo, DetectionResult } from "./utils/types"
11
+ import type { QRScannerOptions } from "./scanner/qr-scanner"
12
+ import type { BarcodeScannerOptions } from "./scanner/barcode-scanner"
13
13
 
14
14
  // 静态导入所有依赖
15
- import { QRScanner } from './scanner/qr-scanner';
16
- import { BarcodeScanner } from './scanner/barcode-scanner';
17
- import { IDCardDetector, IDCardDetectorOptions } from './id-recognition/id-detector';
18
- import { OCRProcessor } from './id-recognition/ocr-processor';
19
- import { DataExtractor } from './id-recognition/data-extractor';
20
- import { ImageProcessor } from './utils/image-processing';
15
+ import { QRScanner } from "./scanner/qr-scanner"
16
+ import { BarcodeScanner } from "./scanner/barcode-scanner"
17
+ import {
18
+ IDCardDetector,
19
+ IDCardDetectorOptions,
20
+ } from "./id-recognition/id-detector"
21
+ import { OCRProcessor } from "./id-recognition/ocr-processor"
22
+ import { DataExtractor } from "./id-recognition/data-extractor"
23
+ import { ImageProcessor } from "./utils/image-processing"
24
+ // 导入IDScannerDemo
25
+ import { IDScannerDemo } from "./demo/demo"
21
26
 
22
27
  /**
23
28
  * IDScanner配置选项接口
24
29
  */
25
30
  export interface IDScannerOptions {
26
- cameraOptions?: CameraOptions;
27
- qrScannerOptions?: QRScannerOptions;
28
- barcodeScannerOptions?: BarcodeScannerOptions;
29
- onQRCodeScanned?: (result: string) => void;
30
- onBarcodeScanned?: (result: string) => void;
31
- onIDCardScanned?: (info: IDCardInfo) => void;
32
- onError?: (error: Error) => void;
31
+ cameraOptions?: CameraOptions
32
+ qrScannerOptions?: QRScannerOptions
33
+ barcodeScannerOptions?: BarcodeScannerOptions
34
+ onQRCodeScanned?: (result: string) => void
35
+ onBarcodeScanned?: (result: string) => void
36
+ onIDCardScanned?: (info: IDCardInfo) => void
37
+ onError?: (error: Error) => void
33
38
  }
34
39
 
35
40
  /**
@@ -37,23 +42,26 @@ export interface IDScannerOptions {
37
42
  * UMD版本使用静态导入实现
38
43
  */
39
44
  export class IDScanner {
40
- private camera: Camera;
41
- private qrScanner: QRScanner | null = null;
42
- private barcodeScanner: BarcodeScanner | null = null;
43
- private idDetector: IDCardDetector | null = null;
44
- private ocrProcessor: OCRProcessor | null = null;
45
- private dataExtractor: DataExtractor | null = null;
46
- private scanMode: 'qr' | 'barcode' | 'idcard' = 'qr';
47
- private videoElement: HTMLVideoElement | null = null;
48
-
45
+ private camera: Camera
46
+ private qrScanner: QRScanner | null = null
47
+ private barcodeScanner: BarcodeScanner | null = null
48
+ private idDetector: IDCardDetector | null = null
49
+ private ocrProcessor: OCRProcessor | null = null
50
+ private dataExtractor: DataExtractor | null = null
51
+ private scanMode: "qr" | "barcode" | "idcard" = "qr"
52
+ private videoElement: HTMLVideoElement | null = null
53
+
54
+ // 添加静态属性IDScannerDemo,使其能被通过IDScanner.IDScannerDemo访问
55
+ static IDScannerDemo = IDScannerDemo
56
+
49
57
  /**
50
58
  * 构造函数
51
59
  * @param options 配置选项
52
60
  */
53
61
  constructor(private options: IDScannerOptions = {}) {
54
- this.camera = new Camera(options.cameraOptions);
62
+ this.camera = new Camera(options.cameraOptions)
55
63
  }
56
-
64
+
57
65
  /**
58
66
  * 初始化模块
59
67
  * 根据需要初始化OCR引擎
@@ -61,180 +69,409 @@ export class IDScanner {
61
69
  async initialize(): Promise<void> {
62
70
  try {
63
71
  // 初始化OCR模块
64
- this.ocrProcessor = new OCRProcessor();
65
- this.dataExtractor = new DataExtractor();
66
- await this.ocrProcessor.initialize();
67
-
68
- console.log('IDScanner initialized');
72
+ this.ocrProcessor = new OCRProcessor()
73
+ this.dataExtractor = new DataExtractor()
74
+ await this.ocrProcessor.initialize()
75
+
76
+ console.log("IDScanner initialized")
69
77
  } catch (error) {
70
- this.handleError(error as Error);
71
- throw error;
78
+ this.handleError(error as Error)
79
+ throw error
72
80
  }
73
81
  }
74
-
82
+
75
83
  /**
76
84
  * 启动二维码扫描
77
85
  * @param videoElement HTML视频元素
78
86
  */
79
87
  async startQRScanner(videoElement: HTMLVideoElement): Promise<void> {
80
- this.stop();
81
- this.videoElement = videoElement;
82
- this.scanMode = 'qr';
83
-
88
+ this.stop()
89
+ this.videoElement = videoElement
90
+ this.scanMode = "qr"
91
+
84
92
  try {
85
93
  if (!this.qrScanner) {
86
94
  this.qrScanner = new QRScanner({
87
95
  ...this.options.qrScannerOptions,
88
- onScan: this.handleQRScan.bind(this)
89
- });
96
+ onScan: this.handleQRScan.bind(this),
97
+ })
90
98
  }
91
-
92
- await this.camera.start(videoElement);
93
- this.qrScanner.start(videoElement);
99
+
100
+ await this.camera.start(videoElement)
101
+ this.qrScanner.start(videoElement)
94
102
  } catch (error) {
95
- this.handleError(error as Error);
103
+ this.handleError(error as Error)
96
104
  }
97
105
  }
98
-
106
+
99
107
  /**
100
108
  * 启动条形码扫描
101
109
  * @param videoElement HTML视频元素
102
110
  */
103
111
  async startBarcodeScanner(videoElement: HTMLVideoElement): Promise<void> {
104
- this.stop();
105
- this.videoElement = videoElement;
106
- this.scanMode = 'barcode';
107
-
112
+ this.stop()
113
+ this.videoElement = videoElement
114
+ this.scanMode = "barcode"
115
+
108
116
  try {
109
117
  if (!this.barcodeScanner) {
110
118
  this.barcodeScanner = new BarcodeScanner({
111
119
  ...this.options.barcodeScannerOptions,
112
- onScan: this.handleBarcodeScan.bind(this)
113
- });
120
+ onScan: this.handleBarcodeScan.bind(this),
121
+ })
114
122
  }
115
-
116
- await this.camera.start(videoElement);
117
- this.barcodeScanner.start(videoElement);
123
+
124
+ await this.camera.start(videoElement)
125
+ this.barcodeScanner.start(videoElement)
118
126
  } catch (error) {
119
- this.handleError(error as Error);
127
+ this.handleError(error as Error)
120
128
  }
121
129
  }
122
-
130
+
123
131
  /**
124
132
  * 启动身份证扫描
125
133
  * @param videoElement HTML视频元素
126
134
  */
127
135
  async startIDCardScanner(videoElement: HTMLVideoElement): Promise<void> {
128
- this.stop();
129
- this.videoElement = videoElement;
130
- this.scanMode = 'idcard';
131
-
136
+ this.stop()
137
+ this.videoElement = videoElement
138
+ this.scanMode = "idcard"
139
+
132
140
  try {
133
141
  if (!this.ocrProcessor) {
134
- await this.initialize();
142
+ await this.initialize()
135
143
  }
136
-
144
+
137
145
  if (!this.idDetector) {
138
146
  this.idDetector = new IDCardDetector({
139
147
  onDetection: this.handleIDDetection.bind(this),
140
- onError: this.handleError.bind(this)
141
- } as IDCardDetectorOptions);
148
+ onError: this.handleError.bind(this),
149
+ } as IDCardDetectorOptions)
142
150
  }
143
-
144
- await this.camera.start(videoElement);
145
- this.idDetector.start(videoElement);
151
+
152
+ await this.camera.start(videoElement)
153
+ this.idDetector.start(videoElement)
146
154
  } catch (error) {
147
- this.handleError(error as Error);
155
+ this.handleError(error as Error)
148
156
  }
149
157
  }
150
-
158
+
151
159
  /**
152
160
  * 停止扫描
153
161
  */
154
162
  stop(): void {
155
- if (this.scanMode === 'qr' && this.qrScanner) {
156
- this.qrScanner.stop();
157
- } else if (this.scanMode === 'barcode' && this.barcodeScanner) {
158
- this.barcodeScanner.stop();
159
- } else if (this.scanMode === 'idcard' && this.idDetector) {
160
- this.idDetector.stop();
163
+ if (this.scanMode === "qr" && this.qrScanner) {
164
+ this.qrScanner.stop()
165
+ } else if (this.scanMode === "barcode" && this.barcodeScanner) {
166
+ this.barcodeScanner.stop()
167
+ } else if (this.scanMode === "idcard" && this.idDetector) {
168
+ this.idDetector.stop()
161
169
  }
162
-
163
- this.camera.stop();
170
+
171
+ this.camera.stop()
164
172
  }
165
-
173
+
166
174
  /**
167
175
  * 处理二维码扫描结果
168
176
  */
169
177
  private handleQRScan(result: string): void {
170
178
  if (this.options.onQRCodeScanned) {
171
- this.options.onQRCodeScanned(result);
179
+ this.options.onQRCodeScanned(result)
172
180
  }
173
181
  }
174
-
182
+
175
183
  /**
176
184
  * 处理条形码扫描结果
177
185
  */
178
186
  private handleBarcodeScan(result: string): void {
179
187
  if (this.options.onBarcodeScanned) {
180
- this.options.onBarcodeScanned(result);
188
+ this.options.onBarcodeScanned(result)
181
189
  }
182
190
  }
183
-
191
+
184
192
  /**
185
193
  * 处理身份证检测结果
186
194
  */
187
195
  private async handleIDDetection(result: DetectionResult): Promise<void> {
188
- if (!this.ocrProcessor || !this.dataExtractor) return;
189
-
196
+ if (!this.ocrProcessor || !this.dataExtractor) return
197
+
190
198
  try {
191
199
  // 检查 imageData 是否存在
192
200
  if (!result.imageData) {
193
- this.handleError(new Error('无效的图像数据'));
194
- return;
201
+ this.handleError(new Error("无效的图像数据"))
202
+ return
195
203
  }
196
-
197
- const idCardInfo = await this.ocrProcessor.processIDCard(result.imageData);
198
- const extractedInfo = this.dataExtractor.extractAndValidate(idCardInfo);
199
-
204
+
205
+ const idCardInfo = await this.ocrProcessor.processIDCard(result.imageData)
206
+ const extractedInfo = this.dataExtractor.extractAndValidate(idCardInfo)
207
+
200
208
  if (this.options.onIDCardScanned) {
201
- this.options.onIDCardScanned(extractedInfo);
209
+ this.options.onIDCardScanned(extractedInfo)
202
210
  }
203
211
  } catch (error) {
204
- this.handleError(error as Error);
212
+ this.handleError(error as Error)
205
213
  }
206
214
  }
207
-
215
+
208
216
  /**
209
217
  * 处理错误
210
218
  */
211
219
  private handleError(error: Error): void {
212
220
  if (this.options.onError) {
213
- this.options.onError(error);
221
+ this.options.onError(error)
214
222
  } else {
215
- console.error('IDScanner error:', error);
223
+ console.error("IDScanner error:", error)
216
224
  }
217
225
  }
218
-
226
+
219
227
  /**
220
228
  * 释放资源
221
229
  */
222
230
  async terminate(): Promise<void> {
223
- this.stop();
224
-
231
+ this.stop()
232
+
225
233
  if (this.ocrProcessor) {
226
- await this.ocrProcessor.terminate();
227
- this.ocrProcessor = null;
234
+ await this.ocrProcessor.terminate()
235
+ this.ocrProcessor = null
236
+ }
237
+
238
+ this.qrScanner = null
239
+ this.barcodeScanner = null
240
+ this.idDetector = null
241
+ this.dataExtractor = null
242
+ }
243
+
244
+ /**
245
+ * 处理图片中的二维码
246
+ * @param imageSource 图片源,可以是Image元素、Canvas元素或URL字符串
247
+ * @returns 返回Promise,解析为扫描结果
248
+ */
249
+ async processQRCodeImage(
250
+ imageSource: HTMLImageElement | HTMLCanvasElement | string
251
+ ): Promise<string> {
252
+ try {
253
+ if (!this.qrScanner) {
254
+ this.qrScanner = new QRScanner({
255
+ ...this.options.qrScannerOptions,
256
+ onScan: this.handleQRScan.bind(this),
257
+ })
258
+ }
259
+
260
+ // 处理不同类型的图片源
261
+ let imageElement: HTMLImageElement
262
+ if (typeof imageSource === "string") {
263
+ // 如果是URL字符串,创建新的Image元素并加载图片
264
+ imageElement = new Image()
265
+ imageElement.crossOrigin = "anonymous" // 处理跨域图片
266
+ await new Promise((resolve, reject) => {
267
+ imageElement.onload = resolve
268
+ imageElement.onerror = reject
269
+ imageElement.src = imageSource
270
+ })
271
+ } else if (imageSource instanceof HTMLImageElement) {
272
+ // 如果已经是Image元素,直接使用
273
+ imageElement = imageSource
274
+ } else if (imageSource instanceof HTMLCanvasElement) {
275
+ // 如果是Canvas元素,创建新的Image元素并从Canvas获取数据
276
+ const dataURL = imageSource.toDataURL()
277
+ imageElement = new Image()
278
+ await new Promise((resolve, reject) => {
279
+ imageElement.onload = resolve
280
+ imageElement.onerror = reject
281
+ imageElement.src = dataURL
282
+ })
283
+ } else {
284
+ throw new Error("不支持的图片源类型")
285
+ }
286
+
287
+ // 创建Canvas处理图片
288
+ const canvas = document.createElement("canvas")
289
+ const ctx = canvas.getContext("2d")
290
+ if (!ctx) {
291
+ throw new Error("无法创建Canvas上下文")
292
+ }
293
+
294
+ // 设置Canvas尺寸与图片相同
295
+ canvas.width = imageElement.naturalWidth
296
+ canvas.height = imageElement.naturalHeight
297
+ ctx.drawImage(imageElement, 0, 0)
298
+
299
+ // 获取图像数据并处理
300
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
301
+ return new Promise((resolve, reject) => {
302
+ try {
303
+ const result = this.qrScanner?.processImageData(imageData)
304
+ if (result) {
305
+ resolve(result)
306
+ } else {
307
+ reject(new Error("未检测到二维码"))
308
+ }
309
+ } catch (error) {
310
+ reject(error)
311
+ }
312
+ })
313
+ } catch (error) {
314
+ this.handleError(error as Error)
315
+ throw error
316
+ }
317
+ }
318
+
319
+ /**
320
+ * 处理图片中的条形码
321
+ * @param imageSource 图片源,可以是Image元素、Canvas元素或URL字符串
322
+ * @returns 返回Promise,解析为扫描结果
323
+ */
324
+ async processBarcodeImage(
325
+ imageSource: HTMLImageElement | HTMLCanvasElement | string
326
+ ): Promise<string> {
327
+ try {
328
+ if (!this.barcodeScanner) {
329
+ this.barcodeScanner = new BarcodeScanner({
330
+ ...this.options.barcodeScannerOptions,
331
+ onScan: this.handleBarcodeScan.bind(this),
332
+ })
333
+ }
334
+
335
+ // 处理不同类型的图片源
336
+ let imageElement: HTMLImageElement
337
+ if (typeof imageSource === "string") {
338
+ // 如果是URL字符串,创建新的Image元素并加载图片
339
+ imageElement = new Image()
340
+ imageElement.crossOrigin = "anonymous" // 处理跨域图片
341
+ await new Promise((resolve, reject) => {
342
+ imageElement.onload = resolve
343
+ imageElement.onerror = reject
344
+ imageElement.src = imageSource
345
+ })
346
+ } else if (imageSource instanceof HTMLImageElement) {
347
+ // 如果已经是Image元素,直接使用
348
+ imageElement = imageSource
349
+ } else if (imageSource instanceof HTMLCanvasElement) {
350
+ // 如果是Canvas元素,创建新的Image元素并从Canvas获取数据
351
+ const dataURL = imageSource.toDataURL()
352
+ imageElement = new Image()
353
+ await new Promise((resolve, reject) => {
354
+ imageElement.onload = resolve
355
+ imageElement.onerror = reject
356
+ imageElement.src = dataURL
357
+ })
358
+ } else {
359
+ throw new Error("不支持的图片源类型")
360
+ }
361
+
362
+ // 创建Canvas处理图片
363
+ const canvas = document.createElement("canvas")
364
+ const ctx = canvas.getContext("2d")
365
+ if (!ctx) {
366
+ throw new Error("无法创建Canvas上下文")
367
+ }
368
+
369
+ // 设置Canvas尺寸与图片相同
370
+ canvas.width = imageElement.naturalWidth
371
+ canvas.height = imageElement.naturalHeight
372
+ ctx.drawImage(imageElement, 0, 0)
373
+
374
+ // 获取图像数据并处理
375
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
376
+ return new Promise((resolve, reject) => {
377
+ try {
378
+ const result = this.barcodeScanner?.processImageData(imageData)
379
+ if (result) {
380
+ resolve(result)
381
+ } else {
382
+ reject(new Error("未检测到条形码"))
383
+ }
384
+ } catch (error) {
385
+ reject(error)
386
+ }
387
+ })
388
+ } catch (error) {
389
+ this.handleError(error as Error)
390
+ throw error
391
+ }
392
+ }
393
+
394
+ /**
395
+ * 处理图片中的身份证
396
+ * @param imageSource 图片源,可以是Image元素、Canvas元素或URL字符串
397
+ * @returns 返回Promise,解析为身份证信息
398
+ */
399
+ async processIDCardImage(
400
+ imageSource: HTMLImageElement | HTMLCanvasElement | string
401
+ ): Promise<IDCardInfo> {
402
+ try {
403
+ if (!this.ocrProcessor || !this.dataExtractor) {
404
+ await this.initialize()
405
+ }
406
+
407
+ // 处理不同类型的图片源
408
+ let imageElement: HTMLImageElement
409
+ if (typeof imageSource === "string") {
410
+ // 如果是URL字符串,创建新的Image元素并加载图片
411
+ imageElement = new Image()
412
+ imageElement.crossOrigin = "anonymous" // 处理跨域图片
413
+ await new Promise((resolve, reject) => {
414
+ imageElement.onload = resolve
415
+ imageElement.onerror = reject
416
+ imageElement.src = imageSource
417
+ })
418
+ } else if (imageSource instanceof HTMLImageElement) {
419
+ // 如果已经是Image元素,直接使用
420
+ imageElement = imageSource
421
+ } else if (imageSource instanceof HTMLCanvasElement) {
422
+ // 如果是Canvas元素,创建新的Image元素并从Canvas获取数据
423
+ const dataURL = imageSource.toDataURL()
424
+ imageElement = new Image()
425
+ await new Promise((resolve, reject) => {
426
+ imageElement.onload = resolve
427
+ imageElement.onerror = reject
428
+ imageElement.src = dataURL
429
+ })
430
+ } else {
431
+ throw new Error("不支持的图片源类型")
432
+ }
433
+
434
+ // 创建Canvas处理图片
435
+ const canvas = document.createElement("canvas")
436
+ const ctx = canvas.getContext("2d")
437
+ if (!ctx) {
438
+ throw new Error("无法创建Canvas上下文")
439
+ }
440
+
441
+ // 设置Canvas尺寸与图片相同
442
+ canvas.width = imageElement.naturalWidth
443
+ canvas.height = imageElement.naturalHeight
444
+ ctx.drawImage(imageElement, 0, 0)
445
+
446
+ // 获取图像数据并处理
447
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
448
+
449
+ // 调用OCR处理器处理身份证图像
450
+ const ocrResult = await this.ocrProcessor!.processIDCard(imageData)
451
+ const extractedInfo = this.dataExtractor!.extractAndValidate(ocrResult)
452
+
453
+ if (this.options.onIDCardScanned) {
454
+ this.options.onIDCardScanned(extractedInfo)
455
+ }
456
+
457
+ return extractedInfo
458
+ } catch (error) {
459
+ this.handleError(error as Error)
460
+ throw error
228
461
  }
229
-
230
- this.qrScanner = null;
231
- this.barcodeScanner = null;
232
- this.idDetector = null;
233
- this.dataExtractor = null;
234
462
  }
235
463
  }
236
464
 
237
465
  // 导出核心类型
238
- export { IDCardInfo } from './utils/types';
239
- export { CameraOptions } from './utils/camera';
240
- export { QRScanner, BarcodeScanner, IDCardDetector, OCRProcessor, DataExtractor, ImageProcessor };
466
+ export { IDCardInfo } from "./utils/types"
467
+ export { CameraOptions } from "./utils/camera"
468
+ export {
469
+ QRScanner,
470
+ BarcodeScanner,
471
+ IDCardDetector,
472
+ OCRProcessor,
473
+ DataExtractor,
474
+ ImageProcessor,
475
+ }
476
+ // 导出IDScannerDemo类
477
+ export { IDScannerDemo }