id-scanner-lib 1.3.2 → 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 (115) 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 -77
  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/modules/id-card/anti-fake-detector.ts +732 -0
  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/modules/id-card/ocr-processor.ts +538 -0
  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/browser-image-compression.d.ts +19 -0
  73. package/src/types/tesseract.d.ts +280 -0
  74. package/src/utils/image-processing.ts +432 -49
  75. package/src/utils/index.ts +426 -0
  76. package/src/utils/performance.ts +168 -131
  77. package/src/utils/resource-manager.ts +65 -146
  78. package/src/utils/types.ts +90 -2
  79. package/src/utils/worker.ts +123 -84
  80. package/src/version.ts +11 -0
  81. package/tools/scaffold.js +543 -0
  82. package/dist/id-scanner-core.esm.js +0 -11076
  83. package/dist/id-scanner-core.esm.js.map +0 -1
  84. package/dist/id-scanner-core.js +0 -11088
  85. package/dist/id-scanner-core.js.map +0 -1
  86. package/dist/id-scanner-core.min.js +0 -1
  87. package/dist/id-scanner-core.min.js.map +0 -1
  88. package/dist/id-scanner-ocr.esm.js +0 -1802
  89. package/dist/id-scanner-ocr.esm.js.map +0 -1
  90. package/dist/id-scanner-ocr.js +0 -1811
  91. package/dist/id-scanner-ocr.js.map +0 -1
  92. package/dist/id-scanner-ocr.min.js +0 -1
  93. package/dist/id-scanner-ocr.min.js.map +0 -1
  94. package/dist/id-scanner-qr.esm.js +0 -1023
  95. package/dist/id-scanner-qr.esm.js.map +0 -1
  96. package/dist/id-scanner-qr.js +0 -1032
  97. package/dist/id-scanner-qr.js.map +0 -1
  98. package/dist/id-scanner-qr.min.js +0 -1
  99. package/dist/id-scanner-qr.min.js.map +0 -1
  100. package/dist/id-scanner.js +0 -3740
  101. package/dist/id-scanner.js.map +0 -1
  102. package/dist/id-scanner.min.js +0 -1
  103. package/dist/id-scanner.min.js.map +0 -1
  104. package/src/core.ts +0 -138
  105. package/src/demo/demo.ts +0 -204
  106. package/src/id-recognition/anti-fake-detector.ts +0 -317
  107. package/src/id-recognition/data-extractor.ts +0 -262
  108. package/src/id-recognition/id-detector.ts +0 -363
  109. package/src/id-recognition/ocr-processor.ts +0 -334
  110. package/src/id-recognition/ocr-worker.ts +0 -156
  111. package/src/index-umd.ts +0 -477
  112. package/src/ocr-module.ts +0 -187
  113. package/src/qr-module.ts +0 -179
  114. package/src/scanner/barcode-scanner.ts +0 -251
  115. package/src/scanner/qr-scanner.ts +0 -167
package/src/core.ts DELETED
@@ -1,138 +0,0 @@
1
- /**
2
- * @file 轻量级扫描库核心
3
- * @description 不包含OCR功能的轻量版,只提供二维码和条形码扫描功能
4
- * @module IDScannerCore
5
- * @version 1.0.0
6
- * @license MIT
7
- */
8
-
9
- import { QRScanner, QRScannerOptions } from './scanner/qr-scanner';
10
- import { BarcodeScanner, BarcodeScannerOptions } from './scanner/barcode-scanner';
11
- import { Camera, CameraOptions } from './utils/camera';
12
- import { ImageProcessor } from './utils/image-processing';
13
-
14
- /**
15
- * IDScannerCore配置选项
16
- */
17
- export interface IDScannerCoreOptions {
18
- cameraOptions?: CameraOptions;
19
- qrScannerOptions?: QRScannerOptions;
20
- barcodeScannerOptions?: BarcodeScannerOptions;
21
- onQRCodeScanned?: (result: string) => void;
22
- onBarcodeScanned?: (result: string) => void;
23
- onError?: (error: Error) => void;
24
- }
25
-
26
- /**
27
- * IDScannerCore 轻量级扫描类
28
- *
29
- * 提供二维码和条形码扫描功能,不包含OCR身份证识别功能
30
- */
31
- export class IDScannerCore {
32
- private qrScanner: QRScanner;
33
- private barcodeScanner: BarcodeScanner;
34
- private camera: Camera;
35
- private scanMode: 'qr' | 'barcode' = 'qr';
36
- private videoElement: HTMLVideoElement | null = null;
37
-
38
- /**
39
- * 构造函数
40
- * @param options 配置选项
41
- */
42
- constructor(private options: IDScannerCoreOptions = {}) {
43
- this.camera = new Camera(options.cameraOptions);
44
- this.qrScanner = new QRScanner({
45
- ...options.qrScannerOptions,
46
- onScan: this.handleQRScan.bind(this)
47
- });
48
- this.barcodeScanner = new BarcodeScanner({
49
- ...options.barcodeScannerOptions,
50
- onScan: this.handleBarcodeScan.bind(this)
51
- });
52
- }
53
-
54
- /**
55
- * 初始化扫描器
56
- */
57
- async initialize(): Promise<void> {
58
- // 轻量版无需初始化OCR引擎
59
- console.log('IDScannerCore initialized');
60
- }
61
-
62
- /**
63
- * 启动二维码扫描
64
- * @param videoElement HTML视频元素
65
- */
66
- async startQRScanner(videoElement: HTMLVideoElement): Promise<void> {
67
- this.videoElement = videoElement;
68
- this.scanMode = 'qr';
69
- await this.camera.start(videoElement);
70
- this.qrScanner.start(videoElement);
71
- }
72
-
73
- /**
74
- * 启动条形码扫描
75
- * @param videoElement HTML视频元素
76
- */
77
- async startBarcodeScanner(videoElement: HTMLVideoElement): Promise<void> {
78
- this.videoElement = videoElement;
79
- this.scanMode = 'barcode';
80
- await this.camera.start(videoElement);
81
- this.barcodeScanner.start(videoElement);
82
- }
83
-
84
- /**
85
- * 停止扫描
86
- */
87
- stop(): void {
88
- if (this.scanMode === 'qr') {
89
- this.qrScanner.stop();
90
- } else if (this.scanMode === 'barcode') {
91
- this.barcodeScanner.stop();
92
- }
93
- this.camera.stop();
94
- }
95
-
96
- /**
97
- * 处理二维码扫描结果
98
- */
99
- private handleQRScan(result: string): void {
100
- if (this.options.onQRCodeScanned) {
101
- this.options.onQRCodeScanned(result);
102
- }
103
- }
104
-
105
- /**
106
- * 处理条形码扫描结果
107
- */
108
- private handleBarcodeScan(result: string): void {
109
- if (this.options.onBarcodeScanned) {
110
- this.options.onBarcodeScanned(result);
111
- }
112
- }
113
-
114
- /**
115
- * 处理错误
116
- */
117
- private handleError(error: Error): void {
118
- if (this.options.onError) {
119
- this.options.onError(error);
120
- } else {
121
- console.error('IDScannerCore error:', error);
122
- }
123
- }
124
-
125
- /**
126
- * 释放资源
127
- */
128
- async terminate(): Promise<void> {
129
- this.stop();
130
- // 轻量版无需释放OCR资源
131
- }
132
- }
133
-
134
- // 导出相关类型和工具
135
- export { QRScanner, QRScannerOptions } from './scanner/qr-scanner';
136
- export { BarcodeScanner, BarcodeScannerOptions } from './scanner/barcode-scanner';
137
- export { Camera, CameraOptions } from './utils/camera';
138
- export { ImageProcessor } from './utils/image-processing';
package/src/demo/demo.ts DELETED
@@ -1,204 +0,0 @@
1
- import { IDScanner, IDCardInfo } from "../index"
2
-
3
- export class IDScannerDemo {
4
- private scanner: IDScanner
5
- private videoElement: HTMLVideoElement
6
- private resultContainer: HTMLElement
7
- private switchButton: HTMLButtonElement
8
- private imageInput: HTMLInputElement | null = null
9
-
10
- constructor(
11
- videoElementId: string,
12
- resultContainerId: string,
13
- switchButtonId: string,
14
- imageInputId?: string
15
- ) {
16
- // 获取DOM元素
17
- this.videoElement = document.getElementById(
18
- videoElementId
19
- ) as HTMLVideoElement
20
- this.resultContainer = document.getElementById(
21
- resultContainerId
22
- ) as HTMLElement
23
- this.switchButton = document.getElementById(
24
- switchButtonId
25
- ) as HTMLButtonElement
26
-
27
- // 如果提供了图片输入元素ID,初始化图片输入功能
28
- if (imageInputId) {
29
- this.imageInput = document.getElementById(
30
- imageInputId
31
- ) as HTMLInputElement
32
- if (this.imageInput) {
33
- this.imageInput.addEventListener(
34
- "change",
35
- this.handleImageInput.bind(this)
36
- )
37
- }
38
- }
39
-
40
- try {
41
- // 创建IDScanner实例
42
- this.scanner = new IDScanner({
43
- onQRCodeScanned: this.handleQRCodeResult.bind(this),
44
- onBarcodeScanned: this.handleQRCodeResult.bind(this), // 复用QR码结果处理
45
- onIDCardScanned: this.handleIDCardResult.bind(this),
46
- onError: this.handleError.bind(this),
47
- })
48
- } catch (error) {
49
- console.error("创建IDScanner实例失败:", error)
50
- this.handleError(error instanceof Error ? error : new Error("初始化失败"))
51
- // 创建一个空对象以避免空引用错误
52
- this.scanner = {} as IDScanner
53
- }
54
-
55
- // 添加模式切换按钮事件监听
56
- this.switchButton.addEventListener("click", this.toggleScanMode.bind(this))
57
- }
58
-
59
- async initialize(): Promise<void> {
60
- try {
61
- await this.scanner.initialize()
62
- await this.scanner.startQRScanner(this.videoElement)
63
- this.switchButton.textContent = "切换到身份证模式"
64
- this.currentMode = "qr"
65
- } catch (error) {
66
- this.handleError(error instanceof Error ? error : new Error("初始化失败"))
67
- }
68
- }
69
-
70
- private currentMode: "qr" | "barcode" | "idcard" = "qr"
71
-
72
- private async toggleScanMode(): Promise<void> {
73
- try {
74
- this.scanner.stop()
75
-
76
- if (this.currentMode === "qr") {
77
- this.currentMode = "barcode"
78
- await this.scanner.startBarcodeScanner(this.videoElement)
79
- this.switchButton.textContent = "切换到身份证模式"
80
- } else if (this.currentMode === "barcode") {
81
- this.currentMode = "idcard"
82
- await this.scanner.startIDCardScanner(this.videoElement)
83
- this.switchButton.textContent = "切换到二维码模式"
84
- } else {
85
- this.currentMode = "qr"
86
- await this.scanner.startQRScanner(this.videoElement)
87
- this.switchButton.textContent = "切换到条形码模式"
88
- }
89
-
90
- this.resultContainer.innerHTML = ""
91
- } catch (error) {
92
- this.handleError(
93
- error instanceof Error ? error : new Error("切换模式失败")
94
- )
95
- }
96
- }
97
-
98
- /**
99
- * 处理图片输入
100
- * 支持从文件选择器获取图片并进行识别
101
- */
102
- private async handleImageInput(event: Event): Promise<void> {
103
- const input = event.target as HTMLInputElement
104
- if (!input.files || input.files.length === 0) return
105
-
106
- const file = input.files[0]
107
-
108
- try {
109
- // 检查文件类型
110
- if (!file.type.startsWith("image/")) {
111
- throw new Error("请选择图片文件")
112
- }
113
-
114
- // 创建一个本地URL以显示图片
115
- const imageUrl = URL.createObjectURL(file)
116
-
117
- // 显示处理中的提示
118
- this.resultContainer.innerHTML = `
119
- <h3>正在处理图片...</h3>
120
- <img src="${imageUrl}" style="max-width: 100%; max-height: 300px; margin-bottom: 10px;">
121
- `
122
-
123
- // 根据当前模式处理图片
124
- try {
125
- if (this.currentMode === "qr") {
126
- const result = await this.scanner.processQRCodeImage(imageUrl)
127
- if (result) {
128
- this.handleQRCodeResult(result)
129
- }
130
- } else if (this.currentMode === "barcode") {
131
- const result = await this.scanner.processBarcodeImage(imageUrl)
132
- if (result) {
133
- this.handleQRCodeResult(result)
134
- }
135
- } else if (this.currentMode === "idcard") {
136
- const result = await this.scanner.processIDCardImage(imageUrl)
137
- if (result) {
138
- this.handleIDCardResult(result)
139
- }
140
- }
141
- } catch (error) {
142
- // 如果处理失败,显示错误
143
- this.resultContainer.innerHTML = `
144
- <h3>识别结果:</h3>
145
- <img src="${imageUrl}" style="max-width: 100%; max-height: 300px; margin-bottom: 10px;">
146
- <p class="error">未能识别内容,请尝试其他图片或调整图片质量</p>
147
- <p class="error">${
148
- error instanceof Error ? error.message : "未知错误"
149
- }</p>
150
- `
151
- }
152
-
153
- // 清除文件选择,允许再次选择相同的文件
154
- input.value = ""
155
- } catch (error) {
156
- this.handleError(
157
- error instanceof Error ? error : new Error(String(error))
158
- )
159
-
160
- // 清除文件选择
161
- input.value = ""
162
- }
163
- }
164
-
165
- private handleQRCodeResult(result: string): void {
166
- this.resultContainer.innerHTML = `
167
- <h3>扫描结果:</h3>
168
- <p>${result}</p>
169
- `
170
- }
171
-
172
- private handleIDCardResult(info: IDCardInfo): void {
173
- this.resultContainer.innerHTML = `
174
- <h3>身份证信息:</h3>
175
- <p>姓名: ${info.name || "未识别"}</p>
176
- <p>性别: ${info.gender || "未识别"}</p>
177
- <p>民族: ${info.nationality || "未识别"}</p>
178
- <p>出生日期: ${info.birthDate || "未识别"}</p>
179
- <p>地址: ${info.address || "未识别"}</p>
180
- <p>身份证号: ${info.idNumber || "未识别"}</p>
181
- <p>签发机关: ${info.issuingAuthority || "未识别"}</p>
182
- <p>有效期限: ${info.validPeriod || "未识别"}</p>
183
- `
184
- }
185
-
186
- private handleError(error: Error): void {
187
- console.error("扫描错误:", error)
188
- this.resultContainer.innerHTML = `
189
- <div class="error">
190
- <h3>错误:</h3>
191
- <p>${error.message}</p>
192
- </div>
193
- `
194
- }
195
-
196
- stop(): void {
197
- if (this.scanner && typeof this.scanner.stop === "function") {
198
- this.scanner.stop()
199
- }
200
- if (this.scanner && typeof this.scanner.terminate === "function") {
201
- this.scanner.terminate()
202
- }
203
- }
204
- }
@@ -1,317 +0,0 @@
1
- /**
2
- * @file 身份证防伪检测模块
3
- * @description 提供身份证防伪特征识别功能,区分真假身份证
4
- * @module AntiFakeDetector
5
- */
6
-
7
- import { ImageProcessor } from "../utils/image-processing"
8
- import { LRUCache, calculateImageFingerprint } from "../utils/performance"
9
- import { Disposable } from "../utils/resource-manager"
10
-
11
- /**
12
- * 防伪检测结果
13
- */
14
- export interface AntiFakeDetectionResult {
15
- isAuthentic: boolean // 是否为真实身份证
16
- confidence: number // 置信度(0-1)
17
- detectedFeatures: string[] // 检测到的防伪特征
18
- message: string // 结果描述
19
- processingTime?: number // 处理时间(ms)
20
- }
21
-
22
- /**
23
- * 防伪检测器配置选项
24
- */
25
- export interface AntiFakeDetectorOptions {
26
- sensitivity?: number // 敏感度 (0-1),值越高越严格
27
- enableCache?: boolean // 是否启用缓存
28
- cacheSize?: number // 缓存大小
29
- logger?: (message: any) => void // 日志记录器
30
- }
31
-
32
- /**
33
- * 身份证防伪特征检测器
34
- *
35
- * 基于图像分析技术检测身份证中的多种防伪特征,包括:
36
- * 1. 荧光油墨特征
37
- * 2. 微缩文字
38
- * 3. 光变图案
39
- * 4. 雕刻凹印
40
- * 5. 隐形图案
41
- *
42
- * @example
43
- * ```typescript
44
- * // 创建防伪检测器
45
- * const antiFakeDetector = new AntiFakeDetector({
46
- * sensitivity: 0.8,
47
- * enableCache: true
48
- * });
49
- *
50
- * // 分析身份证图像
51
- * const imageData = await ImageProcessor.createImageDataFromFile(idCardFile);
52
- * const result = await antiFakeDetector.detect(imageData);
53
- *
54
- * if (result.isAuthentic) {
55
- * console.log('身份证真实,检测到防伪特征:', result.detectedFeatures);
56
- * } else {
57
- * console.log('警告!', result.message);
58
- * }
59
- * ```
60
- */
61
- export class AntiFakeDetector implements Disposable {
62
- private options: Required<AntiFakeDetectorOptions>
63
- private resultCache: LRUCache<string, AntiFakeDetectionResult>
64
-
65
- /**
66
- * 创建身份证防伪检测器实例
67
- *
68
- * @param options 防伪检测器配置
69
- */
70
- constructor(options: AntiFakeDetectorOptions = {}) {
71
- this.options = {
72
- sensitivity: 0.7,
73
- enableCache: true,
74
- cacheSize: 50,
75
- logger: console.log,
76
- ...options,
77
- }
78
-
79
- // 初始化缓存
80
- this.resultCache = new LRUCache<string, AntiFakeDetectionResult>(
81
- this.options.cacheSize
82
- )
83
- }
84
-
85
- /**
86
- * 检测身份证图像的防伪特征
87
- *
88
- * @param imageData 身份证图像数据
89
- * @returns 防伪检测结果
90
- */
91
- async detect(imageData: ImageData): Promise<AntiFakeDetectionResult> {
92
- const startTime = performance.now()
93
-
94
- // 检查缓存
95
- if (this.options.enableCache) {
96
- const fingerprint = calculateImageFingerprint(imageData)
97
- const cachedResult = this.resultCache.get(fingerprint)
98
-
99
- if (cachedResult) {
100
- this.options.logger("使用缓存的防伪检测结果")
101
- return cachedResult
102
- }
103
- }
104
-
105
- // 图像预处理增强防伪特征
106
- const enhancedImage = this.enhanceAntiFakeFeatures(imageData)
107
-
108
- // 执行多种防伪特征检测
109
- const featureResults = await Promise.all([
110
- this.detectUVInkFeatures(enhancedImage),
111
- this.detectMicroText(enhancedImage),
112
- this.detectOpticalVariable(enhancedImage),
113
- this.detectIntaglioPrinting(enhancedImage),
114
- this.detectGhostImage(enhancedImage),
115
- ])
116
-
117
- // 汇总检测结果
118
- const detectedFeatures: string[] = []
119
- let totalConfidence = 0
120
-
121
- for (const [feature, detected, confidence] of featureResults) {
122
- if (detected && confidence > 0.5) {
123
- detectedFeatures.push(feature)
124
- totalConfidence += confidence
125
- }
126
- }
127
-
128
- // 计算最终结果
129
- const normalizedConfidence =
130
- featureResults.length > 0 ? totalConfidence / featureResults.length : 0
131
-
132
- // 根据敏感度和检测到的特征决定是否通过验证
133
- const isAuthentic =
134
- normalizedConfidence >= this.options.sensitivity &&
135
- detectedFeatures.length >= 2
136
-
137
- // 生成结果消息
138
- let message = isAuthentic
139
- ? `身份证真实,检测到${detectedFeatures.length}个防伪特征`
140
- : detectedFeatures.length > 0
141
- ? `可疑身份证,仅检测到${detectedFeatures.length}个防伪特征,置信度不足`
142
- : "未检测到有效防伪特征,可能为伪造证件"
143
-
144
- const result: AntiFakeDetectionResult = {
145
- isAuthentic,
146
- confidence: normalizedConfidence,
147
- detectedFeatures,
148
- message,
149
- processingTime: performance.now() - startTime,
150
- }
151
-
152
- // 缓存结果
153
- if (this.options.enableCache) {
154
- const fingerprint = calculateImageFingerprint(imageData)
155
- this.resultCache.set(fingerprint, result)
156
- }
157
-
158
- return result
159
- }
160
-
161
- /**
162
- * 增强身份证图像中的防伪特征
163
- *
164
- * @param imageData 原始图像数据
165
- * @returns 增强后的图像数据
166
- * @private
167
- */
168
- private enhanceAntiFakeFeatures(imageData: ImageData): ImageData {
169
- // 应用特定的图像处理增强防伪特征
170
- return ImageProcessor.batchProcess(imageData, {
171
- contrast: 30, // 增强对比度
172
- brightness: 10, // 轻微提高亮度
173
- sharpen: true, // 锐化图像突出细节
174
- })
175
- }
176
-
177
- /**
178
- * 检测荧光油墨特征
179
- *
180
- * @param imageData 图像数据
181
- * @returns [特征名称, 是否检测到, 置信度]
182
- * @private
183
- */
184
- private async detectUVInkFeatures(
185
- imageData: ImageData
186
- ): Promise<[string, boolean, number]> {
187
- // 提取蓝色通道增强UV油墨可见度
188
- const canvas = document.createElement("canvas")
189
- canvas.width = imageData.width
190
- canvas.height = imageData.height
191
- const ctx = canvas.getContext("2d")
192
-
193
- if (!ctx) {
194
- return ["荧光油墨", false, 0]
195
- }
196
-
197
- ctx.putImageData(imageData, 0, 0)
198
-
199
- // 分析蓝色通道中的特定模式
200
- // 实际实现中应使用更复杂的算法提取UV特征
201
- // 这里使用模拟实现
202
-
203
- // 模拟检测: 70%的概率检测到,置信度0.65-0.95
204
- const detected = Math.random() > 0.3
205
- const confidence = detected ? 0.65 + Math.random() * 0.3 : 0
206
-
207
- return ["荧光油墨", detected, confidence]
208
- }
209
-
210
- /**
211
- * 检测微缩文字
212
- *
213
- * @param imageData 图像数据
214
- * @returns [特征名称, 是否检测到, 置信度]
215
- * @private
216
- */
217
- private async detectMicroText(
218
- imageData: ImageData
219
- ): Promise<[string, boolean, number]> {
220
- // 应用边缘检测突出微缩文字
221
- const grayscale = ImageProcessor.toGrayscale(
222
- new ImageData(
223
- new Uint8ClampedArray(imageData.data),
224
- imageData.width,
225
- imageData.height
226
- )
227
- )
228
-
229
- // 寻找特定的微缩文字模式
230
- // 实际实现中应使用计算机视觉算法寻找微小规则文字模式
231
- // 这里使用模拟实现
232
-
233
- // 模拟检测: 80%的概率检测到,置信度0.7-0.95
234
- const detected = Math.random() > 0.2
235
- const confidence = detected ? 0.7 + Math.random() * 0.25 : 0
236
-
237
- return ["微缩文字", detected, confidence]
238
- }
239
-
240
- /**
241
- * 检测光变图案
242
- *
243
- * @param imageData 图像数据
244
- * @returns [特征名称, 是否检测到, 置信度]
245
- * @private
246
- */
247
- private async detectOpticalVariable(
248
- imageData: ImageData
249
- ): Promise<[string, boolean, number]> {
250
- // 提取特定区域并分析颜色变化
251
- // 在实际实现中需要定位光变图案区域并分析其特征
252
- // 这里使用模拟实现
253
-
254
- // 模拟检测: 65%的概率检测到,置信度0.6-0.9
255
- const detected = Math.random() > 0.35
256
- const confidence = detected ? 0.6 + Math.random() * 0.3 : 0
257
-
258
- return ["光变图案", detected, confidence]
259
- }
260
-
261
- /**
262
- * 检测凹印雕刻特征
263
- *
264
- * @param imageData 图像数据
265
- * @returns [特征名称, 是否检测到, 置信度]
266
- * @private
267
- */
268
- private async detectIntaglioPrinting(
269
- imageData: ImageData
270
- ): Promise<[string, boolean, number]> {
271
- // 使用特定滤镜增强凹印效果
272
- // 在实际实现中应分析阴影和纹理模式
273
- // 这里使用模拟实现
274
-
275
- // 模拟检测: 75%的概率检测到,置信度0.65-0.9
276
- const detected = Math.random() > 0.25
277
- const confidence = detected ? 0.65 + Math.random() * 0.25 : 0
278
-
279
- return ["雕刻凹印", detected, confidence]
280
- }
281
-
282
- /**
283
- * 检测隐形图案(幽灵图像)
284
- *
285
- * @param imageData 图像数据
286
- * @returns [特征名称, 是否检测到, 置信度]
287
- * @private
288
- */
289
- private async detectGhostImage(
290
- imageData: ImageData
291
- ): Promise<[string, boolean, number]> {
292
- // 调整对比度和亮度显现隐形图案
293
- // 在实际实现中应使用特定滤镜和图像处理算法
294
- // 这里使用模拟实现
295
-
296
- // 模拟检测: 60%的概率检测到,置信度0.55-0.85
297
- const detected = Math.random() > 0.4
298
- const confidence = detected ? 0.55 + Math.random() * 0.3 : 0
299
-
300
- return ["隐形图案", detected, confidence]
301
- }
302
-
303
- /**
304
- * 清除结果缓存
305
- */
306
- clearCache(): void {
307
- this.resultCache.clear()
308
- this.options.logger("防伪检测结果缓存已清除")
309
- }
310
-
311
- /**
312
- * 释放资源
313
- */
314
- dispose(): void {
315
- this.resultCache.clear()
316
- }
317
- }