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.
- package/README.md +55 -460
- package/dist/id-scanner-lib.esm.js +4641 -0
- package/dist/id-scanner-lib.esm.js.map +1 -0
- package/dist/id-scanner-lib.js +14755 -0
- package/dist/id-scanner-lib.js.map +1 -0
- package/dist/types/core/base-module.d.ts +44 -0
- package/dist/types/core/camera-manager.d.ts +258 -0
- package/dist/types/core/config.d.ts +88 -0
- package/dist/types/core/errors.d.ts +111 -0
- package/dist/types/core/event-emitter.d.ts +55 -0
- package/dist/types/core/logger.d.ts +277 -0
- package/dist/types/core/module-manager.d.ts +78 -0
- package/dist/types/core/plugin-manager.d.ts +158 -0
- package/dist/types/core/resource-manager.d.ts +246 -0
- package/dist/types/core/result.d.ts +83 -0
- package/dist/types/core/scanner-factory.d.ts +93 -0
- package/dist/types/index.bundle.d.ts +1303 -0
- package/dist/types/index.d.ts +86 -0
- package/dist/types/interfaces/external-types.d.ts +174 -0
- package/dist/types/interfaces/face-detection.d.ts +293 -0
- package/dist/types/interfaces/scanner-module.d.ts +280 -0
- package/dist/types/modules/face/face-detector.d.ts +170 -0
- package/dist/types/modules/face/index.d.ts +56 -0
- package/dist/types/modules/face/liveness-detector.d.ts +177 -0
- package/dist/types/modules/face/types.d.ts +136 -0
- package/dist/types/modules/id-card/anti-fake-detector.d.ts +170 -0
- package/dist/types/modules/id-card/id-card-detector.d.ts +131 -0
- package/dist/types/modules/id-card/index.d.ts +89 -0
- package/dist/types/modules/id-card/ocr-processor.d.ts +110 -0
- package/dist/types/modules/id-card/ocr-worker.d.ts +31 -0
- package/dist/types/modules/id-card/types.d.ts +181 -0
- package/dist/types/modules/qrcode/index.d.ts +51 -0
- package/dist/types/modules/qrcode/qr-code-scanner.d.ts +64 -0
- package/dist/types/modules/qrcode/types.d.ts +67 -0
- package/dist/types/utils/camera.d.ts +81 -0
- package/dist/types/utils/image-processing.d.ts +176 -0
- package/dist/types/utils/index.d.ts +175 -0
- package/dist/types/utils/performance.d.ts +81 -0
- package/dist/types/utils/resource-manager.d.ts +53 -0
- package/dist/types/utils/types.d.ts +166 -0
- package/dist/types/utils/worker.d.ts +52 -0
- package/dist/types/version.d.ts +7 -0
- package/package.json +76 -75
- package/src/core/base-module.ts +78 -0
- package/src/core/camera-manager.ts +798 -0
- package/src/core/config.ts +268 -0
- package/src/core/errors.ts +174 -0
- package/src/core/event-emitter.ts +110 -0
- package/src/core/logger.ts +549 -0
- package/src/core/module-manager.ts +165 -0
- package/src/core/plugin-manager.ts +429 -0
- package/src/core/resource-manager.ts +762 -0
- package/src/core/result.ts +163 -0
- package/src/core/scanner-factory.ts +237 -0
- package/src/index.ts +113 -936
- package/src/interfaces/external-types.ts +200 -0
- package/src/interfaces/face-detection.ts +309 -0
- package/src/interfaces/scanner-module.ts +384 -0
- package/src/modules/face/face-detector.ts +931 -0
- package/src/modules/face/index.ts +208 -0
- package/src/modules/face/liveness-detector.ts +908 -0
- package/src/modules/face/types.ts +133 -0
- package/src/{id-recognition → modules/id-card}/anti-fake-detector.ts +273 -239
- package/src/modules/id-card/id-card-detector.ts +474 -0
- package/src/modules/id-card/index.ts +425 -0
- package/src/{id-recognition → modules/id-card}/ocr-processor.ts +149 -92
- package/src/modules/id-card/ocr-worker.ts +259 -0
- package/src/modules/id-card/types.ts +178 -0
- package/src/modules/qrcode/index.ts +175 -0
- package/src/modules/qrcode/qr-code-scanner.ts +230 -0
- package/src/modules/qrcode/types.ts +65 -0
- package/src/types/tesseract.d.ts +265 -22
- package/src/utils/image-processing.ts +68 -49
- package/src/utils/index.ts +426 -0
- package/src/utils/performance.ts +168 -131
- package/src/utils/resource-manager.ts +65 -146
- package/src/utils/types.ts +90 -2
- package/src/utils/worker.ts +123 -84
- package/src/version.ts +11 -0
- package/tools/scaffold.js +543 -0
- package/dist/id-scanner-core.esm.js +0 -11349
- package/dist/id-scanner-core.js +0 -11361
- package/dist/id-scanner-core.min.js +0 -1
- package/dist/id-scanner-ocr.esm.js +0 -2319
- package/dist/id-scanner-ocr.js +0 -2328
- package/dist/id-scanner-ocr.min.js +0 -1
- package/dist/id-scanner-qr.esm.js +0 -1296
- package/dist/id-scanner-qr.js +0 -1305
- package/dist/id-scanner-qr.min.js +0 -1
- package/dist/id-scanner.js +0 -4561
- package/dist/id-scanner.min.js +0 -1
- package/src/core.ts +0 -138
- package/src/demo/demo.ts +0 -204
- package/src/id-recognition/data-extractor.ts +0 -262
- package/src/id-recognition/id-detector.ts +0 -510
- package/src/id-recognition/ocr-worker.ts +0 -156
- package/src/index-umd.ts +0 -477
- package/src/ocr-module.ts +0 -187
- package/src/qr-module.ts +0 -179
- package/src/scanner/barcode-scanner.ts +0 -251
- package/src/scanner/qr-scanner.ts +0 -167
package/src/utils/types.ts
CHANGED
|
@@ -70,12 +70,100 @@ export interface DetectionResult {
|
|
|
70
70
|
* ```
|
|
71
71
|
*/
|
|
72
72
|
export interface IDCardInfo {
|
|
73
|
+
/** 姓名 */
|
|
73
74
|
name?: string;
|
|
75
|
+
/** 性别 */
|
|
74
76
|
gender?: string;
|
|
75
|
-
|
|
77
|
+
/** 民族 */
|
|
78
|
+
ethnicity?: string;
|
|
79
|
+
/** 出生日期 */
|
|
76
80
|
birthDate?: string;
|
|
81
|
+
/** 地址 */
|
|
77
82
|
address?: string;
|
|
83
|
+
/** 身份证号码 */
|
|
78
84
|
idNumber?: string;
|
|
79
|
-
|
|
85
|
+
/** 签发机关 */
|
|
86
|
+
issueAuthority?: string;
|
|
87
|
+
/** 有效期起始日期 */
|
|
88
|
+
validFrom?: string;
|
|
89
|
+
/** 有效期截止日期 */
|
|
90
|
+
validTo?: string;
|
|
91
|
+
/** 有效期限(完整文本) */
|
|
80
92
|
validPeriod?: string;
|
|
93
|
+
/** 照片区域 */
|
|
94
|
+
photoRegion?: {
|
|
95
|
+
x: number;
|
|
96
|
+
y: number;
|
|
97
|
+
width: number;
|
|
98
|
+
height: number;
|
|
99
|
+
};
|
|
100
|
+
/** 类型 */
|
|
101
|
+
type?: string;
|
|
102
|
+
/** 置信度 */
|
|
103
|
+
confidence?: number;
|
|
104
|
+
/** 其他属性 */
|
|
105
|
+
[key: string]: any;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 点坐标
|
|
110
|
+
*/
|
|
111
|
+
export interface Point {
|
|
112
|
+
x: number;
|
|
113
|
+
y: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 矩形区域
|
|
118
|
+
*/
|
|
119
|
+
export interface Rect {
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 可释放资源接口
|
|
128
|
+
*/
|
|
129
|
+
export interface Disposable {
|
|
130
|
+
/** 释放资源 */
|
|
131
|
+
dispose(): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 图像处理选项
|
|
136
|
+
*/
|
|
137
|
+
export interface ImageProcessingOptions {
|
|
138
|
+
/** 亮度调整 (-100 到 100) */
|
|
139
|
+
brightness?: number;
|
|
140
|
+
/** 对比度调整 (-100 到 100) */
|
|
141
|
+
contrast?: number;
|
|
142
|
+
/** 饱和度调整 (-100 到 100) */
|
|
143
|
+
saturation?: number;
|
|
144
|
+
/** 锐化强度 (0 到 10) */
|
|
145
|
+
sharpen?: number | boolean;
|
|
146
|
+
/** 高斯模糊半径 (0 到 10) */
|
|
147
|
+
blur?: number;
|
|
148
|
+
/** 是否应用灰度转换 */
|
|
149
|
+
grayscale?: boolean;
|
|
150
|
+
/** 是否应用二值化 */
|
|
151
|
+
binarize?: boolean;
|
|
152
|
+
/** 二值化阈值 (0 到 255) */
|
|
153
|
+
threshold?: number;
|
|
154
|
+
/** 是否应用边缘检测 */
|
|
155
|
+
edgeDetection?: boolean;
|
|
156
|
+
/** 是否应用降噪 */
|
|
157
|
+
denoise?: boolean;
|
|
158
|
+
/** 是否应用直方图均衡化 */
|
|
159
|
+
histogramEqualization?: boolean;
|
|
160
|
+
/** 是否应用透视校正 */
|
|
161
|
+
perspectiveCorrection?: boolean;
|
|
162
|
+
/** 透视校正点 */
|
|
163
|
+
perspectivePoints?: {
|
|
164
|
+
topLeft: Point;
|
|
165
|
+
topRight: Point;
|
|
166
|
+
bottomRight: Point;
|
|
167
|
+
bottomLeft: Point;
|
|
168
|
+
};
|
|
81
169
|
}
|
package/src/utils/worker.ts
CHANGED
|
@@ -1,173 +1,212 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
3
|
-
* @description 提供Worker
|
|
4
|
-
* @module
|
|
2
|
+
* @file Worker工具
|
|
3
|
+
* @description 提供Web Worker相关的工具函数
|
|
4
|
+
* @module utils/worker
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @param workerFunction 要在Worker中执行的函数
|
|
11
|
-
* @returns 返回包含发送消息方法的Worker控制对象
|
|
8
|
+
* 检查是否支持Web Worker
|
|
9
|
+
* @returns 是否支持Web Worker
|
|
12
10
|
*/
|
|
13
|
-
export function
|
|
14
|
-
|
|
11
|
+
export function isWorkerSupported(): boolean {
|
|
12
|
+
return typeof Worker !== 'undefined';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 创建Worker
|
|
17
|
+
* @param workerFunction Worker函数
|
|
18
|
+
* @returns Worker实例
|
|
19
|
+
*/
|
|
20
|
+
export function createWorker<TInput, TOutput>(
|
|
21
|
+
workerFunction: (input: TInput) => TOutput | Promise<TOutput>
|
|
22
|
+
): {
|
|
23
|
+
postMessage: (input: TInput) => Promise<TOutput>;
|
|
15
24
|
terminate: () => void;
|
|
16
25
|
} {
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
// 检查是否支持Web Worker
|
|
27
|
+
if (!isWorkerSupported()) {
|
|
28
|
+
// 回退到主线程执行
|
|
29
|
+
return {
|
|
30
|
+
postMessage: async (input: TInput) => {
|
|
31
|
+
return await Promise.resolve(workerFunction(input));
|
|
32
|
+
},
|
|
33
|
+
terminate: () => {}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 将函数转换为字符串
|
|
38
|
+
const workerFunctionStr = workerFunction.toString();
|
|
39
|
+
|
|
40
|
+
// 创建Worker脚本
|
|
41
|
+
const workerScript = `
|
|
42
|
+
// 定义Worker函数
|
|
43
|
+
const workerFunction = ${workerFunctionStr};
|
|
44
|
+
|
|
45
|
+
// 监听消息
|
|
46
|
+
self.addEventListener('message', async (event) => {
|
|
20
47
|
try {
|
|
21
|
-
const
|
|
48
|
+
const input = event.data;
|
|
49
|
+
const result = await workerFunction(input);
|
|
22
50
|
self.postMessage({ success: true, result });
|
|
23
51
|
} catch (error) {
|
|
24
52
|
self.postMessage({
|
|
25
53
|
success: false,
|
|
26
|
-
error:
|
|
54
|
+
error: error instanceof Error ? error.message : String(error)
|
|
27
55
|
});
|
|
28
56
|
}
|
|
29
|
-
}
|
|
57
|
+
});
|
|
30
58
|
`;
|
|
31
59
|
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const
|
|
60
|
+
// 创建Blob URL
|
|
61
|
+
const blob = new Blob([workerScript], { type: 'application/javascript' });
|
|
62
|
+
const url = URL.createObjectURL(blob);
|
|
35
63
|
|
|
36
|
-
//
|
|
64
|
+
// 创建Worker
|
|
65
|
+
const worker = new Worker(url);
|
|
66
|
+
|
|
67
|
+
// 创建Promise映射
|
|
37
68
|
const promiseMap = new Map<number, {
|
|
38
|
-
resolve: (value:
|
|
69
|
+
resolve: (value: TOutput) => void;
|
|
39
70
|
reject: (reason: any) => void;
|
|
40
71
|
}>();
|
|
41
72
|
|
|
73
|
+
// 消息计数器
|
|
42
74
|
let messageCounter = 0;
|
|
43
75
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
URL.revokeObjectURL(workerUrl);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const { id, success, result, error } = e.data;
|
|
76
|
+
// 监听Worker消息
|
|
77
|
+
worker.addEventListener('message', (event) => {
|
|
78
|
+
const { messageId, success, result, error } = event.data;
|
|
51
79
|
|
|
52
|
-
|
|
80
|
+
// 查找对应的Promise
|
|
81
|
+
const promiseHandlers = promiseMap.get(messageId);
|
|
53
82
|
if (promiseHandlers) {
|
|
54
|
-
promiseMap.delete(id);
|
|
55
|
-
|
|
56
83
|
if (success) {
|
|
57
84
|
promiseHandlers.resolve(result);
|
|
58
85
|
} else {
|
|
59
|
-
|
|
60
|
-
workerError.stack = error.stack;
|
|
61
|
-
promiseHandlers.reject(workerError);
|
|
86
|
+
promiseHandlers.reject(new Error(error));
|
|
62
87
|
}
|
|
88
|
+
|
|
89
|
+
// 删除Promise映射
|
|
90
|
+
promiseMap.delete(messageId);
|
|
63
91
|
}
|
|
64
|
-
};
|
|
65
|
-
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// 返回Worker接口
|
|
66
95
|
return {
|
|
67
|
-
postMessage: (
|
|
68
|
-
return new Promise((resolve, reject) => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
96
|
+
postMessage: (input: TInput): Promise<TOutput> => {
|
|
97
|
+
return new Promise<TOutput>((resolve, reject) => {
|
|
98
|
+
// 生成消息ID
|
|
99
|
+
const messageId = messageCounter++;
|
|
100
|
+
|
|
101
|
+
// 保存Promise处理函数
|
|
102
|
+
promiseMap.set(messageId, { resolve, reject });
|
|
103
|
+
|
|
104
|
+
// 发送消息到Worker
|
|
105
|
+
worker.postMessage({ messageId, input });
|
|
72
106
|
});
|
|
73
107
|
},
|
|
74
108
|
terminate: () => {
|
|
109
|
+
// 终止Worker
|
|
75
110
|
worker.terminate();
|
|
111
|
+
|
|
112
|
+
// 释放Blob URL
|
|
113
|
+
URL.revokeObjectURL(url);
|
|
114
|
+
|
|
115
|
+
// 拒绝所有未完成的Promise
|
|
116
|
+
for (const [, { reject }] of promiseMap) {
|
|
117
|
+
reject(new Error('Worker已终止'));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 清空Promise映射
|
|
76
121
|
promiseMap.clear();
|
|
77
|
-
URL.revokeObjectURL(workerUrl);
|
|
78
122
|
}
|
|
79
123
|
};
|
|
80
124
|
}
|
|
81
125
|
|
|
82
|
-
/**
|
|
83
|
-
* 判断浏览器是否支持Web Workers
|
|
84
|
-
*
|
|
85
|
-
* @returns 是否支持Web Workers
|
|
86
|
-
*/
|
|
87
|
-
export function isWorkerSupported(): boolean {
|
|
88
|
-
return typeof Worker !== 'undefined';
|
|
89
|
-
}
|
|
90
|
-
|
|
91
126
|
/**
|
|
92
127
|
* 工作线程池
|
|
93
128
|
* 用于管理和重用Worker线程,避免频繁创建和销毁
|
|
94
129
|
*/
|
|
95
130
|
export class WorkerPool<T, R> {
|
|
96
131
|
private workers: Array<{
|
|
97
|
-
worker: ReturnType<typeof createWorker<T, R
|
|
98
|
-
busy: boolean
|
|
99
|
-
}> = []
|
|
100
|
-
|
|
132
|
+
worker: ReturnType<typeof createWorker<T, R>>
|
|
133
|
+
busy: boolean
|
|
134
|
+
}> = []
|
|
135
|
+
|
|
101
136
|
/**
|
|
102
137
|
* 创建工作线程池
|
|
103
|
-
*
|
|
138
|
+
*
|
|
104
139
|
* @param workerFunction 要在Worker中执行的函数
|
|
105
140
|
* @param size 池中Worker的数量
|
|
106
141
|
*/
|
|
107
|
-
constructor(
|
|
142
|
+
constructor(
|
|
143
|
+
private workerFunction: (data: T) => Promise<R> | R,
|
|
144
|
+
private size: number = navigator.hardwareConcurrency || 4
|
|
145
|
+
) {
|
|
146
|
+
// 更精确的 workerFunction 类型
|
|
108
147
|
// 预创建Workers
|
|
109
148
|
for (let i = 0; i < size; i++) {
|
|
110
149
|
this.workers.push({
|
|
111
150
|
worker: createWorker<T, R>(workerFunction),
|
|
112
|
-
busy: false
|
|
113
|
-
})
|
|
151
|
+
busy: false,
|
|
152
|
+
})
|
|
114
153
|
}
|
|
115
154
|
}
|
|
116
|
-
|
|
155
|
+
|
|
117
156
|
/**
|
|
118
157
|
* 获取一个可用的Worker
|
|
119
|
-
*
|
|
158
|
+
*
|
|
120
159
|
* @returns Worker包装对象
|
|
121
160
|
*/
|
|
122
161
|
private getAvailableWorker(): ReturnType<typeof createWorker<T, R>> {
|
|
123
162
|
// 找到第一个空闲的Worker
|
|
124
|
-
const availableWorker = this.workers.find(w => !w.busy)
|
|
125
|
-
|
|
163
|
+
const availableWorker = this.workers.find((w) => !w.busy)
|
|
164
|
+
|
|
126
165
|
if (availableWorker) {
|
|
127
|
-
availableWorker.busy = true
|
|
128
|
-
return availableWorker.worker
|
|
166
|
+
availableWorker.busy = true
|
|
167
|
+
return availableWorker.worker
|
|
129
168
|
}
|
|
130
|
-
|
|
169
|
+
|
|
131
170
|
// 如果没有空闲Worker,创建一个新的
|
|
132
|
-
const worker = createWorker<T, R>(this.workerFunction)
|
|
133
|
-
this.workers.push({ worker, busy: true })
|
|
134
|
-
return worker
|
|
171
|
+
const worker = createWorker<T, R>(this.workerFunction)
|
|
172
|
+
this.workers.push({ worker, busy: true })
|
|
173
|
+
return worker
|
|
135
174
|
}
|
|
136
|
-
|
|
175
|
+
|
|
137
176
|
/**
|
|
138
177
|
* 执行任务
|
|
139
|
-
*
|
|
178
|
+
*
|
|
140
179
|
* @param data 要处理的数据
|
|
141
180
|
* @returns 处理结果的Promise
|
|
142
181
|
*/
|
|
143
182
|
async execute(data: T): Promise<R> {
|
|
144
|
-
const worker = this.getAvailableWorker()
|
|
145
|
-
|
|
183
|
+
const worker = this.getAvailableWorker()
|
|
184
|
+
|
|
146
185
|
try {
|
|
147
|
-
const result = await worker.postMessage(data)
|
|
186
|
+
const result = await worker.postMessage(data)
|
|
148
187
|
// 标记Worker为空闲
|
|
149
|
-
const workerEntry = this.workers.find(w => w.worker === worker)
|
|
188
|
+
const workerEntry = this.workers.find((w) => w.worker === worker)
|
|
150
189
|
if (workerEntry) {
|
|
151
|
-
workerEntry.busy = false
|
|
190
|
+
workerEntry.busy = false
|
|
152
191
|
}
|
|
153
|
-
return result
|
|
192
|
+
return result
|
|
154
193
|
} catch (error) {
|
|
155
194
|
// 出错时也标记为空闲
|
|
156
|
-
const workerEntry = this.workers.find(w => w.worker === worker)
|
|
195
|
+
const workerEntry = this.workers.find((w) => w.worker === worker)
|
|
157
196
|
if (workerEntry) {
|
|
158
|
-
workerEntry.busy = false
|
|
197
|
+
workerEntry.busy = false
|
|
159
198
|
}
|
|
160
|
-
throw error
|
|
199
|
+
throw error
|
|
161
200
|
}
|
|
162
201
|
}
|
|
163
|
-
|
|
202
|
+
|
|
164
203
|
/**
|
|
165
204
|
* 终止所有Worker
|
|
166
205
|
*/
|
|
167
206
|
terminate(): void {
|
|
168
207
|
this.workers.forEach(({ worker }) => {
|
|
169
|
-
worker.terminate()
|
|
170
|
-
})
|
|
171
|
-
this.workers = []
|
|
208
|
+
worker.terminate()
|
|
209
|
+
})
|
|
210
|
+
this.workers = []
|
|
172
211
|
}
|
|
173
|
-
}
|
|
212
|
+
}
|