id-scanner-lib 1.3.3 → 1.6.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.
- package/README.md +324 -410
- package/dist/id-scanner-lib.esm.js +4826 -0
- package/dist/id-scanner-lib.esm.js.map +1 -0
- package/dist/id-scanner-lib.js +4858 -0
- package/dist/id-scanner-lib.js.map +1 -0
- package/dist/types/browser-image-compression.d.ts +19 -0
- package/dist/types/tesseract.d.ts +280 -0
- package/package.json +89 -78
- package/src/core/base-module.ts +78 -0
- package/src/core/camera-manager.ts +813 -0
- package/src/core/config.ts +305 -0
- package/src/core/errors.ts +174 -0
- package/src/core/event-emitter.test.ts +42 -0
- package/src/core/event-emitter.ts +110 -0
- package/src/core/loading-state.test.ts +67 -0
- package/src/core/loading-state.ts +156 -0
- package/src/core/logger.test.ts +49 -0
- package/src/core/logger.ts +549 -0
- package/src/core/module-manager.ts +163 -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 +236 -0
- package/src/index.ts +117 -939
- 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 +988 -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 +274 -240
- 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 +231 -0
- package/src/modules/qrcode/types.ts +169 -0
- package/src/types/common.test.ts +99 -0
- package/src/types/common.ts +166 -0
- package/src/types/tesseract.d.ts +265 -22
- package/src/utils/camera.test.ts +30 -0
- package/src/utils/camera.ts +4 -1
- package/src/utils/error-handler.test.ts +137 -0
- package/src/utils/error-handler.ts +110 -0
- package/src/utils/image-processing.ts +68 -49
- package/src/utils/index.test.ts +186 -0
- package/src/utils/index.ts +429 -0
- package/src/utils/performance.ts +168 -131
- package/src/utils/resource-manager.ts +65 -146
- package/src/utils/retry.test.ts +142 -0
- package/src/utils/retry.ts +282 -0
- package/src/utils/types.ts +90 -2
- package/src/utils/utils.test.ts +171 -0
- 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
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 二维码模块类型定义
|
|
3
|
+
* @description 二维码模块相关的类型和接口定义
|
|
4
|
+
* @module modules/qrcode/types
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 支持的条码格式
|
|
9
|
+
*/
|
|
10
|
+
export enum BarcodeFormat {
|
|
11
|
+
/** QR码 */
|
|
12
|
+
QR_CODE = 'qrcode',
|
|
13
|
+
/** Code 128 */
|
|
14
|
+
CODE_128 = 'code_128',
|
|
15
|
+
/** Code 39 */
|
|
16
|
+
CODE_39 = 'code_39',
|
|
17
|
+
/** Code 93 */
|
|
18
|
+
CODE_93 = 'code_93',
|
|
19
|
+
/** EAN-13 */
|
|
20
|
+
EAN_13 = 'ean_13',
|
|
21
|
+
/** EAN-8 */
|
|
22
|
+
EAN_8 = 'ean_8',
|
|
23
|
+
/** UPC-A */
|
|
24
|
+
UPC_A = 'upc_a',
|
|
25
|
+
/** UPC-E */
|
|
26
|
+
UPC_E = 'upc_e',
|
|
27
|
+
/** ITF */
|
|
28
|
+
ITF = 'itf',
|
|
29
|
+
/** PDF417 */
|
|
30
|
+
PDF_417 = 'pdf_417',
|
|
31
|
+
/** DataMatrix */
|
|
32
|
+
DATA_MATRIX = 'data_matrix',
|
|
33
|
+
/** Aztec */
|
|
34
|
+
AZTEC = 'aztec',
|
|
35
|
+
/** Codabar */
|
|
36
|
+
CODABAR = 'codabar',
|
|
37
|
+
/** Industrial 2 of 5 */
|
|
38
|
+
INDUSTRIAL_2_OF_5 = 'industrial_2_of_5',
|
|
39
|
+
/** QR Code Micro */
|
|
40
|
+
QR_CODE_MICRO = 'qr_code_micro'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 默认支持的格式
|
|
45
|
+
*/
|
|
46
|
+
export const DEFAULT_FORMATS = [
|
|
47
|
+
BarcodeFormat.QR_CODE,
|
|
48
|
+
BarcodeFormat.CODE_128,
|
|
49
|
+
BarcodeFormat.CODE_39,
|
|
50
|
+
BarcodeFormat.EAN_13
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 二维码/条码检测结果
|
|
55
|
+
*/
|
|
56
|
+
export interface QRCodeResult {
|
|
57
|
+
/** 条码内容 */
|
|
58
|
+
data: string;
|
|
59
|
+
|
|
60
|
+
/** 条码格式 */
|
|
61
|
+
barcodeFormat: BarcodeFormat;
|
|
62
|
+
|
|
63
|
+
/** 条码类型 (兼容旧版) */
|
|
64
|
+
type?: string;
|
|
65
|
+
|
|
66
|
+
/** 条码边界框 */
|
|
67
|
+
boundingBox: {
|
|
68
|
+
topLeft: { x: number; y: number };
|
|
69
|
+
topRight: { x: number; y: number };
|
|
70
|
+
bottomRight: { x: number; y: number };
|
|
71
|
+
bottomLeft: { x: number; y: number };
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** 条码中心点 */
|
|
75
|
+
center: { x: number; y: number };
|
|
76
|
+
|
|
77
|
+
/** 原始图像 */
|
|
78
|
+
image?: ImageData;
|
|
79
|
+
|
|
80
|
+
/** 置信度 */
|
|
81
|
+
confidence?: number;
|
|
82
|
+
|
|
83
|
+
/** 原始数据 (解码后的字节) */
|
|
84
|
+
rawBytes?: Uint8Array;
|
|
85
|
+
|
|
86
|
+
/** 错误校正级别 (QR码) */
|
|
87
|
+
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 二维码模块选项
|
|
92
|
+
*/
|
|
93
|
+
export interface QRCodeModuleOptions {
|
|
94
|
+
/** 是否启用模块 */
|
|
95
|
+
enabled?: boolean;
|
|
96
|
+
|
|
97
|
+
/** 扫描配置 */
|
|
98
|
+
scanner?: {
|
|
99
|
+
/** 最小置信度 */
|
|
100
|
+
minConfidence?: number;
|
|
101
|
+
|
|
102
|
+
/** 是否尝试多次扫描 */
|
|
103
|
+
tryMultipleScan?: boolean;
|
|
104
|
+
|
|
105
|
+
/** 是否返回原始图像 */
|
|
106
|
+
returnImage?: boolean;
|
|
107
|
+
|
|
108
|
+
/** 扫描频率 (ms) */
|
|
109
|
+
scanFrequency?: number;
|
|
110
|
+
|
|
111
|
+
/** 启用扫描的格式 */
|
|
112
|
+
formats?: BarcodeFormat[];
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/** 图像处理配置 */
|
|
116
|
+
imageProcess?: {
|
|
117
|
+
/** 是否进行预处理 */
|
|
118
|
+
preprocess?: boolean;
|
|
119
|
+
|
|
120
|
+
/** 是否增强对比度 */
|
|
121
|
+
enhanceContrast?: boolean;
|
|
122
|
+
|
|
123
|
+
/** 二值化阈值 */
|
|
124
|
+
threshold?: number;
|
|
125
|
+
|
|
126
|
+
/** 是否进行降噪 */
|
|
127
|
+
denoise?: boolean;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* 实时扫描选项
|
|
133
|
+
*/
|
|
134
|
+
export interface RealtimeScanOptions {
|
|
135
|
+
/** 视频元素 */
|
|
136
|
+
video: HTMLVideoElement;
|
|
137
|
+
|
|
138
|
+
/** 扫描回调 */
|
|
139
|
+
onResult: (result: QRCodeResult) => void;
|
|
140
|
+
|
|
141
|
+
/** 错误回调 */
|
|
142
|
+
onError?: (error: Error) => void;
|
|
143
|
+
|
|
144
|
+
/** 扫描频率 (ms) */
|
|
145
|
+
frequency?: number;
|
|
146
|
+
|
|
147
|
+
/** 是否连续扫描 */
|
|
148
|
+
continuous?: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 扫描统计信息
|
|
153
|
+
*/
|
|
154
|
+
export interface ScanStats {
|
|
155
|
+
/** 总扫描次数 */
|
|
156
|
+
totalScans: number;
|
|
157
|
+
|
|
158
|
+
/** 成功次数 */
|
|
159
|
+
successfulScans: number;
|
|
160
|
+
|
|
161
|
+
/** 失败次数 */
|
|
162
|
+
failedScans: number;
|
|
163
|
+
|
|
164
|
+
/** 平均处理时间 (ms) */
|
|
165
|
+
avgProcessingTime: number;
|
|
166
|
+
|
|
167
|
+
/** 成功率 */
|
|
168
|
+
successRate: number;
|
|
169
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 通用类型测试
|
|
3
|
+
* @description 测试通用类型
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
Rectangle,
|
|
8
|
+
Point,
|
|
9
|
+
Size,
|
|
10
|
+
ImageSource,
|
|
11
|
+
ModuleState,
|
|
12
|
+
CancellablePromise,
|
|
13
|
+
KeyValuePair
|
|
14
|
+
} from './common';
|
|
15
|
+
|
|
16
|
+
describe('Common Types', () => {
|
|
17
|
+
describe('Rectangle', () => {
|
|
18
|
+
it('should create rectangle', () => {
|
|
19
|
+
const rect: Rectangle = {
|
|
20
|
+
x: 10,
|
|
21
|
+
y: 20,
|
|
22
|
+
width: 100,
|
|
23
|
+
height: 50
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
expect(rect.x).toBe(10);
|
|
27
|
+
expect(rect.y).toBe(20);
|
|
28
|
+
expect(rect.width).toBe(100);
|
|
29
|
+
expect(rect.height).toBe(50);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('Point', () => {
|
|
34
|
+
it('should create point', () => {
|
|
35
|
+
const point: Point = {
|
|
36
|
+
x: 50,
|
|
37
|
+
y: 100
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
expect(point.x).toBe(50);
|
|
41
|
+
expect(point.y).toBe(100);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('Size', () => {
|
|
46
|
+
it('should create size', () => {
|
|
47
|
+
const size: Size = {
|
|
48
|
+
width: 1920,
|
|
49
|
+
height: 1080
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
expect(size.width).toBe(1920);
|
|
53
|
+
expect(size.height).toBe(1080);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('ModuleState', () => {
|
|
58
|
+
it('should have correct states', () => {
|
|
59
|
+
expect(ModuleState.UNINITIALIZED).toBe('uninitialized');
|
|
60
|
+
expect(ModuleState.INITIALIZING).toBe('initializing');
|
|
61
|
+
expect(ModuleState.INITIALIZED).toBe('initialized');
|
|
62
|
+
expect(ModuleState.RUNNING).toBe('running');
|
|
63
|
+
expect(ModuleState.PAUSED).toBe('paused');
|
|
64
|
+
expect(ModuleState.STOPPED).toBe('stopped');
|
|
65
|
+
expect(ModuleState.ERROR).toBe('error');
|
|
66
|
+
expect(ModuleState.DESTROYED).toBe('destroyed');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('CancellablePromise', () => {
|
|
71
|
+
it('should create cancellable promise', () => {
|
|
72
|
+
let cancelled = false;
|
|
73
|
+
|
|
74
|
+
const cp: CancellablePromise<string> = {
|
|
75
|
+
promise: new Promise((resolve) => {
|
|
76
|
+
setTimeout(() => resolve('done'), 100);
|
|
77
|
+
}),
|
|
78
|
+
cancel: () => {
|
|
79
|
+
cancelled = true;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
expect(cp.promise).toBeInstanceOf(Promise);
|
|
84
|
+
expect(typeof cp.cancel).toBe('function');
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('KeyValuePair', () => {
|
|
89
|
+
it('should create key value pair', () => {
|
|
90
|
+
const pair: KeyValuePair<string, number> = {
|
|
91
|
+
key: 'age',
|
|
92
|
+
value: 25
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
expect(pair.key).toBe('age');
|
|
96
|
+
expect(pair.value).toBe(25);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 通用类型定义
|
|
3
|
+
* @description 提供项目通用的类型定义
|
|
4
|
+
* @module types/common
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 基础结果接口
|
|
9
|
+
*/
|
|
10
|
+
export interface BaseResult<T = unknown> {
|
|
11
|
+
/** 是否成功 */
|
|
12
|
+
success: boolean;
|
|
13
|
+
/** 结果数据 */
|
|
14
|
+
data?: T;
|
|
15
|
+
/** 错误信息 */
|
|
16
|
+
error?: string;
|
|
17
|
+
/** 错误码 */
|
|
18
|
+
code?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 分页结果接口
|
|
23
|
+
*/
|
|
24
|
+
export interface PaginatedResult<T> {
|
|
25
|
+
/** 数据列表 */
|
|
26
|
+
items: T[];
|
|
27
|
+
/** 总数 */
|
|
28
|
+
total: number;
|
|
29
|
+
/** 当前页码 */
|
|
30
|
+
page: number;
|
|
31
|
+
/** 每页大小 */
|
|
32
|
+
pageSize: number;
|
|
33
|
+
/** 是否有下一页 */
|
|
34
|
+
hasMore: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 通用配置接口
|
|
39
|
+
*/
|
|
40
|
+
export interface GenericConfig {
|
|
41
|
+
/** 启用状态 */
|
|
42
|
+
enabled?: boolean;
|
|
43
|
+
/** 调试模式 */
|
|
44
|
+
debug?: boolean;
|
|
45
|
+
/** 超时时间(ms) */
|
|
46
|
+
timeout?: number;
|
|
47
|
+
/** 重试次数 */
|
|
48
|
+
retries?: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 回调函数类型
|
|
53
|
+
*/
|
|
54
|
+
export type Callback<T = unknown> = (error?: Error, result?: T) => void;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 异步回调函数类型
|
|
58
|
+
*/
|
|
59
|
+
export type AsyncCallback<T = unknown> = (error?: Error, result?: T) => Promise<void>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 可取消的 Promise
|
|
63
|
+
*/
|
|
64
|
+
export interface CancellablePromise<T> {
|
|
65
|
+
/** Promise 对象 */
|
|
66
|
+
promise: Promise<T>;
|
|
67
|
+
/** 取消函数 */
|
|
68
|
+
cancel: () => void;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 事件监听器类型
|
|
73
|
+
*/
|
|
74
|
+
export type EventListener<T = unknown> = (event: T) => void;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 生命周期钩子
|
|
78
|
+
*/
|
|
79
|
+
export interface LifecycleHooks {
|
|
80
|
+
/** 初始化前 */
|
|
81
|
+
onBeforeInit?: () => void | Promise<void>;
|
|
82
|
+
/** 初始化后 */
|
|
83
|
+
onAfterInit?: () => void | Promise<void>;
|
|
84
|
+
/** 销毁前 */
|
|
85
|
+
onBeforeDestroy?: () => void | Promise<void>;
|
|
86
|
+
/** 销毁后 */
|
|
87
|
+
onAfterDestroy?: () => void | Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 模块状态
|
|
92
|
+
*/
|
|
93
|
+
export enum ModuleState {
|
|
94
|
+
/** 未初始化 */
|
|
95
|
+
UNINITIALIZED = 'uninitialized',
|
|
96
|
+
/** 初始化中 */
|
|
97
|
+
INITIALIZING = 'initializing',
|
|
98
|
+
/** 已初始化 */
|
|
99
|
+
INITIALIZED = 'initialized',
|
|
100
|
+
/** 运行中 */
|
|
101
|
+
RUNNING = 'running',
|
|
102
|
+
/** 已暂停 */
|
|
103
|
+
PAUSED = 'paused',
|
|
104
|
+
/** 已停止 */
|
|
105
|
+
STOPPED = 'stopped',
|
|
106
|
+
/** 错误 */
|
|
107
|
+
ERROR = 'error',
|
|
108
|
+
/** 已销毁 */
|
|
109
|
+
DESTROYED = 'destroyed'
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 检测结果基类
|
|
114
|
+
*/
|
|
115
|
+
export interface DetectionResultBase {
|
|
116
|
+
/** 置信度 (0-1) */
|
|
117
|
+
confidence: number;
|
|
118
|
+
/** 边界框 */
|
|
119
|
+
boundingBox?: {
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
};
|
|
125
|
+
/** 时间戳 */
|
|
126
|
+
timestamp: number;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 图像源类型
|
|
131
|
+
*/
|
|
132
|
+
export type ImageSource = string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageData | Blob;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 矩形区域
|
|
136
|
+
*/
|
|
137
|
+
export interface Rectangle {
|
|
138
|
+
x: number;
|
|
139
|
+
y: number;
|
|
140
|
+
width: number;
|
|
141
|
+
height: number;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 点
|
|
146
|
+
*/
|
|
147
|
+
export interface Point {
|
|
148
|
+
x: number;
|
|
149
|
+
y: number;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 尺寸
|
|
154
|
+
*/
|
|
155
|
+
export interface Size {
|
|
156
|
+
width: number;
|
|
157
|
+
height: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* 键值对
|
|
162
|
+
*/
|
|
163
|
+
export interface KeyValuePair<K = string, V = unknown> {
|
|
164
|
+
key: K;
|
|
165
|
+
value: V;
|
|
166
|
+
}
|