id-scanner-lib 1.3.0 → 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.
package/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  纯前端实现的TypeScript身份证与二维码识别库,无需后端支持,所有处理均在浏览器端完成。结合高性能图像处理与OCR技术,提供完整的识别解决方案。
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/id-scanner-lib.svg)](https://www.npmjs.com/package/id-scanner-lib)
6
+ [![GitHub Stars](https://img.shields.io/github/stars/agions/id-scanner-lib.svg?style=social)](https://github.com/agions/id-scanner-lib)
7
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/id-scanner-lib)](https://bundlephobia.com/package/id-scanner-lib)
6
8
  [![License](https://img.shields.io/npm/l/id-scanner-lib.svg)](https://github.com/agions/id-scanner-lib/blob/master/LICENSE)
7
9
 
8
10
  ## 技术特性
@@ -11,6 +13,7 @@
11
13
  - **二维码扫描**:基于jsQR实现高精度二维码识别与解码
12
14
  - **条形码识别**:支持EAN-13、CODE-128等常见一维码格式
13
15
  - **身份证OCR**:基于Tesseract.js的优化OCR引擎,精确提取身份证信息
16
+ - **身份证防伪检测**:检测多种防伪特征,有效识别伪造证件
14
17
  - **图像处理优化**:内置多种图像预处理算法,提高识别率
15
18
  - **支持多种数据源**:摄像头实时视频流、图片文件、URL、Base64等
16
19
  - **高效缓存机制**:内置LRU缓存,避免重复识别,提升性能
@@ -25,9 +28,10 @@
25
28
  | 二维码识别 | 50-150ms | >98% | 取决于图像质量 |
26
29
  | 条形码识别 | 70-200ms | >95% | 支持多种格式 |
27
30
  | 身份证OCR | 300-800ms | >90% | 优化后的识别速度 |
31
+ | 防伪检测 | 100-200ms | >85% | 多特征综合分析 |
28
32
  | 图像处理 | 20-100ms | - | 视处理操作而定 |
29
33
 
30
- ## 最新版本 (v1.3.0)
34
+ ## 最新版本 (v1.3.2)
31
35
 
32
36
  - **图像处理引擎升级**:
33
37
  - 增强的图像锐化算法,提高低光照环境下的识别率
@@ -41,30 +45,129 @@
41
45
  - 批量图像处理API
42
46
  - 内置图像压缩功能
43
47
  - 一体化演示组件
48
+ - **身份证防伪检测**:识别多种防伪特征,检测伪造证件
49
+ - 支持荧光油墨、微缩文字、光变图案等5种防伪特征检测
50
+ - 基于多特征综合评分,提供置信度评估
51
+ - 缓存机制提高重复检测性能
44
52
  - **架构改进**:
45
53
  - 资源自动释放机制
46
54
  - 更精细的模块划分
47
55
  - 增强的错误处理
48
56
 
57
+ ## 版本路线图
58
+
59
+ ### v1.4.0:人脸比对与活体检测
60
+
61
+ - **人脸比对模块**:
62
+ - 身份证照片与现场采集照片的比对功能
63
+ - 基于深度学习的人脸特征提取与分析
64
+ - 提供相似度评分与置信度
65
+ - **活体检测**:
66
+ - 眨眼、张嘴等动作检测防止照片欺骗
67
+ - 基于光线反射的3D检测技术
68
+ - 多帧分析提高检测准确率
69
+ - **安全增强**:
70
+ - 本地处理所有数据,保护隐私
71
+ - 结果加密存储选项
72
+ - 合规性验证工具
73
+
74
+ ### v1.5.0:多证件类型支持
75
+
76
+ - **护照识别**:
77
+ - MRZ码(机读区)解析
78
+ - 多国护照模板适配
79
+ - 芯片信息读取(ePassport支持)
80
+ - **驾驶证识别**:
81
+ - 驾驶证OCR识别
82
+ - 驾驶资格与限制条件解析
83
+ - 国际驾照支持
84
+ - **营业执照识别**:
85
+ - 企业信息提取
86
+ - 统一社会信用代码验证
87
+ - 经营范围解析
88
+ - **银行卡识别**:
89
+ - 卡号、有效期识别
90
+ - 银行标识解析
91
+ - BIN码验证
92
+
93
+ ### v1.6.0:UI/UX改进与组件库升级
94
+
95
+ - **现代化UI框架**:
96
+ - 基于Web Components的组件系统
97
+ - 自适应扫描界面
98
+ - 多主题支持(含暗色模式)
99
+ - **交互体验优化**:
100
+ - 实时扫描引导框
101
+ - 智能对焦与取景提示
102
+ - 证件边缘自动检测与校正
103
+ - **可访问性支持**:
104
+ - 屏幕阅读器兼容
105
+ - 键盘导航
106
+ - 多语言本地化
107
+ - **动效与反馈**:
108
+ - 平滑过渡动画
109
+ - 触觉反馈(移动设备)
110
+ - 声音反馈与语音提示
111
+
112
+ ### v1.7.0:性能与架构优化
113
+
114
+ - **WebAssembly实现**:
115
+ - 核心图像处理算法WASM化
116
+ - 性能提升3-5倍
117
+ - 更低的CPU占用
118
+ - **离线支持**:
119
+ - 完整离线运行能力
120
+ - 基于IndexedDB的本地缓存
121
+ - Service Worker支持
122
+ - **微前端集成**:
123
+ - React/Vue/Angular专用组件
124
+ - 更简单的集成API
125
+ - TypeScript类型增强
126
+ - **渐进式加载**:
127
+ - 核心功能快速加载
128
+ - 按需延迟加载附加模块
129
+ - 预测性加载提高响应速度
130
+
131
+ ### v2.0.0:企业级解决方案
132
+
133
+ - **云端协同验证**:
134
+ - 可选云端验证API
135
+ - 本地与云端结果比对
136
+ - 多级安全验证
137
+ - **高级分析功能**:
138
+ - 证件使用统计与分析
139
+ - 风险评估模型
140
+ - 异常检测系统
141
+ - **行业解决方案包**:
142
+ - 金融行业KYC流程集成
143
+ - 酒店/零售快速登记系统
144
+ - 政务/安防高安全性验证
145
+ - **企业级管理功能**:
146
+ - 多租户支持
147
+ - 批量处理队列
148
+ - 完整审计日志
149
+
49
150
  ## 系统架构
50
151
 
51
152
  ```
52
- ┌─────────────────────────────────────────────────────────────┐
153
+ ┌────────────────────────────────────────────────────────────┐
53
154
  │ IDScanner 主模块 │
54
155
  ├─────────────┬─────────────────┬────────────────────────────┤
55
156
  │ QRScanner │ BarcodeScanner │ IDCardDetector │
56
157
  ├─────────────┴─────────────────┴────────────────────────────┤
57
- │ Camera (视频流捕获与处理)
58
- └─────────────────────────────────────────────────────────────┘
158
+ │ Camera (视频流捕获与处理)
159
+ └────────────────────────────────────────────────────────────┘
59
160
 
60
161
 
61
162
 
62
- ┌─────────────────────────────────────────────────────────────┐
163
+ ┌────────────────────────────────────────────────────────────┐
63
164
  │ 核心处理引擎 │
64
165
  ├─────────────────┬─────────────────┬────────────────────────┤
65
166
  │ OCRProcessor │ DataExtractor │ ImageProcessor │
66
- │ (文字识别) │ (数据提取验证) (图像预处理)
67
- └─────────────────┴─────────────────┴────────────────────────┘
167
+ │ (文字识别) │ (数据提取验证) (图像预处理)
168
+ ├─────────────────┴─────────────────┴────────────────────────┤
169
+ │ AntiFakeDetector (身份证防伪检测) │
170
+ └────────────────────────────────────────────────────────────┘
68
171
  ```
69
172
 
70
173
  ## 安装与使用
@@ -79,22 +182,22 @@ npm install id-scanner-lib --save
79
182
 
80
183
  ```html
81
184
  <!-- 生产环境 (压缩版) -->
82
- <script src="https://cdn.jsdelivr.net/npm/id-scanner-lib@1.3.0/dist/id-scanner.min.js"></script>
185
+ <script src="https://cdn.jsdelivr.net/npm/id-scanner-lib@1.3.1/dist/id-scanner.min.js"></script>
83
186
 
84
187
  <!-- 开发环境 (未压缩) -->
85
- <script src="https://cdn.jsdelivr.net/npm/id-scanner-lib@1.3.0/dist/id-scanner.js"></script>
188
+ <script src="https://cdn.jsdelivr.net/npm/id-scanner-lib@1.3.1/dist/id-scanner.js"></script>
86
189
  ```
87
190
 
88
191
  ## 包体积优化
89
192
 
90
- v1.3.0版本通过代码分割和Tree-shaking极大地优化了包体积:
193
+ v1.3.1版本通过代码分割和Tree-shaking极大地优化了包体积:
91
194
 
92
195
  | 模块 | 大小 (gzip) | 说明 |
93
196
  | --------------- | ----------- | ---------------- |
94
- | 完整包(min.js) | 25KB | 包含所有功能 |
95
- | 核心包(min.js) | 90KB | 基础功能,无OCR |
96
- | OCR模块(min.js) | 14KB | 仅文字识别 |
97
- | QR模块(min.js) | 6KB | 仅二维码识别 |
197
+ | 完整包(min.js) | 93KB | 包含所有功能 |
198
+ | 核心包(min.js) | 186KB | 基础功能,无OCR |
199
+ | OCR模块(min.js) | 70KB | 仅文字识别 |
200
+ | QR模块(min.js) | 60KB | 仅二维码识别 |
98
201
  | ESM模块 | 各模块更小 | 支持Tree-shaking |
99
202
 
100
203
  ## 最佳实践:按需引入
@@ -107,7 +210,8 @@ import { IDScanner } from 'id-scanner-lib';
107
210
 
108
211
  const scanner = new IDScanner({
109
212
  onQRCodeScanned: (result) => console.log('扫描结果:', result),
110
- onIDCardScanned: (info) => console.log('身份证信息:', info)
213
+ onIDCardScanned: (info) => console.log('身份证信息:', info),
214
+ onAntiFakeDetected: (result) => console.log('防伪检测结果:', result)
111
215
  });
112
216
  ```
113
217
 
@@ -176,12 +280,57 @@ document.getElementById('fileInput').addEventListener('change', async (e) => {
176
280
  // 处理身份证图像
177
281
  const idInfo = await scanner.processIDCardImage(compressed);
178
282
  console.log('身份证信息:', idInfo);
283
+
284
+ // 检查防伪检测结果
285
+ if (idInfo.antiFakeResult) {
286
+ console.log('防伪检测结果:', idInfo.antiFakeResult);
287
+ if (idInfo.antiFakeResult.isAuthentic) {
288
+ console.log('证件验证通过');
289
+ } else {
290
+ console.log('警告:可能为伪造证件');
291
+ }
292
+ }
179
293
  } catch (error) {
180
294
  console.error('处理失败:', error);
181
295
  }
182
296
  });
183
297
  ```
184
298
 
299
+ ### 身份证防伪检测
300
+
301
+ ```javascript
302
+ import { IDScanner } from 'id-scanner-lib';
303
+
304
+ const scanner = new IDScanner({
305
+ // 防伪检测结果回调
306
+ onAntiFakeDetected: (result) => {
307
+ if (result.isAuthentic) {
308
+ console.log('身份证验证通过,检测到的防伪特征:', result.detectedFeatures);
309
+ } else {
310
+ console.log('警告:可能是伪造证件!', result.message);
311
+ // 显示安全提示
312
+ document.getElementById('warning').style.display = 'block';
313
+ }
314
+ }
315
+ });
316
+
317
+ await scanner.initialize();
318
+
319
+ // 方法1:单独进行防伪检测
320
+ const antiFakeResult = await scanner.detectIDCardAntiFake(idCardImage);
321
+ console.log('防伪检测结果:', antiFakeResult);
322
+ console.log('检测置信度:', antiFakeResult.confidence);
323
+
324
+ // 方法2:身份证识别时自动进行防伪检测
325
+ const idInfo = await scanner.processIDCardImage(idCardImage);
326
+ // 防伪检测结果包含在返回的信息中
327
+ if (idInfo.antiFakeResult && idInfo.antiFakeResult.isAuthentic) {
328
+ // 身份证真实,继续处理
329
+ } else {
330
+ // 提示可能为伪造证件
331
+ }
332
+ ```
333
+
185
334
  ### 使用内置演示组件
186
335
 
187
336
  ```javascript
@@ -243,6 +392,23 @@ OCR引擎基于Tesseract.js进行了一系列优化:
243
392
  3. **多线程处理**:使用Web Worker避免主线程阻塞
244
393
  4. **结果缓存**:相同图像指纹不重复计算,提高响应速度
245
394
 
395
+ ### 身份证防伪检测技术
396
+
397
+ 防伪检测模块能识别身份证中的多种防伪特征:
398
+
399
+ 1. **荧光油墨特征**:检测特定区域的荧光反应模式
400
+ 2. **微缩文字**:识别证件上的微小文字,伪造证件难以复制
401
+ 3. **光变图案**:检测特定角度下的光变效果
402
+ 4. **雕刻凹印**:通过纹理检测特定的凹印模式
403
+ 5. **隐形图案**:识别证件上的幽灵图像和隐形水印
404
+
405
+ 算法结合多种图像处理技术:
406
+
407
+ - 特定光谱通道提取与分析
408
+ - 边缘检测与微文字模式识别
409
+ - 对比度与光照调整突出隐形特征
410
+ - 自适应阈值处理增强识别准确度
411
+
246
412
  ### 图像增强算法
247
413
 
248
414
  针对不同场景提供最佳图像处理策略:
@@ -276,24 +442,55 @@ OCR引擎基于Tesseract.js进行了一系列优化:
276
442
 
277
443
  ## 应用场景
278
444
 
279
- - **网上银行身份验证**:快速验证用户身份信息
280
- - **酒店登记系统**:自动录入住客信息
445
+ - **网上银行身份验证**:快速验证用户身份信息,检测伪造证件
446
+ - **酒店登记系统**:自动录入住客信息并验证证件真伪
281
447
  - **自助服务终端**:无需人工,自动处理证件信息
282
- - **企业内部系统**:员工证件信息采集
448
+ - **企业内部系统**:员工证件信息采集与验证
283
449
  - **活动签到系统**:快速扫码签到与证件登记
284
450
 
285
- ## 后续开发计划
451
+ ## 发布指南
452
+
453
+ ### 发布到NPM
454
+
455
+ ```bash
456
+ # 1. 确保版本号正确
457
+ npm version [patch|minor|major]
458
+
459
+ # 2. 构建生产版本
460
+ npm run build:prod
461
+
462
+ # 3. 发布到NPM
463
+ npm publish
286
464
 
287
- - [ ] 身份证防伪识别功能
288
- - [ ] 护照和其他证件支持
289
- - [ ] 离线模型支持
290
- - [ ] 人脸比对功能
291
- - [ ] WebAssembly优化
465
+ # 4. 生成标签
466
+ git push origin --tags
467
+ ```
468
+
469
+ ### 发布到GitHub
470
+
471
+ ```bash
472
+ # 1. 提交代码变更
473
+ git add .
474
+ git commit -m "发布 v1.x.x"
475
+
476
+ # 2. 推送到GitHub
477
+ git push origin main
478
+
479
+ # 3. 创建Release
480
+ # 访问 https://github.com/agions/id-scanner-lib/releases/new
481
+ # 选择对应的标签,填写Release说明
482
+ ```
292
483
 
293
484
  ## 贡献指南
294
485
 
295
486
  欢迎贡献代码、报告问题或提出新功能建议。请通过GitHub Issues或Pull Requests参与项目。
296
487
 
488
+ 1. Fork项目仓库
489
+ 2. 创建你的特性分支 (`git checkout -b feature/amazing-feature`)
490
+ 3. 提交你的更改 (`git commit -m '添加一些很棒的功能'`)
491
+ 4. 推送到分支 (`git push origin feature/amazing-feature`)
492
+ 5. 打开Pull Request
493
+
297
494
  ## 许可证
298
495
 
299
496
  本项目采用MIT许可证。详见[LICENSE](LICENSE)文件。
@@ -303,5 +500,6 @@ OCR引擎基于Tesseract.js进行了一系列优化:
303
500
  <p align="center">
304
501
  <a href="https://github.com/agions/id-scanner-lib">GitHub</a> •
305
502
  <a href="https://www.npmjs.com/package/id-scanner-lib">NPM</a> •
306
- <a href="https://github.com/agions/id-scanner-lib/issues">Issues</a>
503
+ <a href="https://github.com/agions/id-scanner-lib/issues">Issues</a>
504
+ <a href="https://github.com/agions/id-scanner-lib/releases">Releases</a>
307
505
  </p>
@@ -1081,16 +1081,16 @@ async function processOCRInWorker(input) {
1081
1081
  // 加载Tesseract.js (Worker 环境下动态导入)
1082
1082
  const { createWorker } = await import('tesseract.js');
1083
1083
  // 创建OCR Worker
1084
- const worker = await createWorker(input.tessWorkerOptions || {
1085
- logger: (m) => console.log(m)
1086
- }); // 添加类型断言,避免TypeScript错误
1084
+ const worker = (await createWorker(input.tessWorkerOptions || {
1085
+ logger: (m) => console.log(m),
1086
+ })); // 添加类型断言,避免TypeScript错误
1087
1087
  try {
1088
1088
  // 初始化OCR引擎
1089
1089
  await worker.load();
1090
- await worker.loadLanguage('chi_sim');
1091
- await worker.initialize('chi_sim');
1090
+ await worker.loadLanguage("chi_sim");
1091
+ await worker.initialize("chi_sim");
1092
1092
  await worker.setParameters({
1093
- tessedit_char_whitelist: '0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期'
1093
+ tessedit_char_whitelist: "0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期",
1094
1094
  });
1095
1095
  // 识别图像
1096
1096
  const { data } = await worker.recognize(input.imageBase64);
@@ -1103,7 +1103,7 @@ async function processOCRInWorker(input) {
1103
1103
  // 返回处理结果
1104
1104
  return {
1105
1105
  idCardInfo,
1106
- processingTime
1106
+ processingTime,
1107
1107
  };
1108
1108
  }
1109
1109
  catch (error) {
@@ -1124,7 +1124,7 @@ async function processOCRInWorker(input) {
1124
1124
  function parseIDCardText(text) {
1125
1125
  const info = {};
1126
1126
  // 拆分为行
1127
- const lines = text.split('\n').filter(line => line.trim());
1127
+ const lines = text.split("\n").filter((line) => line.trim());
1128
1128
  // 解析身份证号码(最容易识别的部分)
1129
1129
  const idNumberRegex = /(\d{17}[\dX])/;
1130
1130
  const idNumberMatch = text.match(idNumberRegex);
@@ -1133,8 +1133,9 @@ function parseIDCardText(text) {
1133
1133
  }
1134
1134
  // 解析姓名
1135
1135
  for (const line of lines) {
1136
- if (line.includes('姓名') || line.length < 10 && line.length > 1 && !/\d/.test(line)) {
1137
- info.name = line.replace('姓名', '').trim();
1136
+ if (line.includes("姓名") ||
1137
+ (line.length < 10 && line.length > 1 && !/\d/.test(line))) {
1138
+ info.name = line.replace("姓名", "").trim();
1138
1139
  break;
1139
1140
  }
1140
1141
  }
@@ -1144,7 +1145,9 @@ function parseIDCardText(text) {
1144
1145
  if (genderMatch) {
1145
1146
  info.gender = genderMatch[1];
1146
1147
  const nationalityText = genderMatch[0];
1147
- info.nationality = nationalityText.substring(nationalityText.indexOf(genderMatch[1]) + 1).trim();
1148
+ info.nationality = nationalityText
1149
+ .substring(nationalityText.indexOf(genderMatch[1]) + 1)
1150
+ .trim();
1148
1151
  }
1149
1152
  // 解析出生日期
1150
1153
  const birthDateRegex = /(\d{4})年(\d{1,2})月(\d{1,2})日/;
@@ -1156,19 +1159,19 @@ function parseIDCardText(text) {
1156
1159
  const addressRegex = /住址([\s\S]*?)公民身份号码/;
1157
1160
  const addressMatch = text.match(addressRegex);
1158
1161
  if (addressMatch) {
1159
- info.address = addressMatch[1].replace(/\n/g, '').trim();
1162
+ info.address = addressMatch[1].replace(/\n/g, "").trim();
1160
1163
  }
1161
1164
  // 解析签发机关
1162
1165
  const authorityRegex = /签发机关([\s\S]*?)有效期/;
1163
1166
  const authorityMatch = text.match(authorityRegex);
1164
1167
  if (authorityMatch) {
1165
- info.issuingAuthority = authorityMatch[1].replace(/\n/g, '').trim();
1168
+ info.issuingAuthority = authorityMatch[1].replace(/\n/g, "").trim();
1166
1169
  }
1167
1170
  // 解析有效期限
1168
1171
  const validPeriodRegex = /有效期限([\s\S]*?)(-|至)/;
1169
1172
  const validPeriodMatch = text.match(validPeriodRegex);
1170
1173
  if (validPeriodMatch) {
1171
- info.validPeriod = validPeriodMatch[0].replace('有效期限', '').trim();
1174
+ info.validPeriod = validPeriodMatch[0].replace("有效期限", "").trim();
1172
1175
  }
1173
1176
  return info;
1174
1177
  }
@@ -1085,16 +1085,16 @@
1085
1085
  // 加载Tesseract.js (Worker 环境下动态导入)
1086
1086
  const { createWorker } = await import('tesseract.js');
1087
1087
  // 创建OCR Worker
1088
- const worker = await createWorker(input.tessWorkerOptions || {
1089
- logger: (m) => console.log(m)
1090
- }); // 添加类型断言,避免TypeScript错误
1088
+ const worker = (await createWorker(input.tessWorkerOptions || {
1089
+ logger: (m) => console.log(m),
1090
+ })); // 添加类型断言,避免TypeScript错误
1091
1091
  try {
1092
1092
  // 初始化OCR引擎
1093
1093
  await worker.load();
1094
- await worker.loadLanguage('chi_sim');
1095
- await worker.initialize('chi_sim');
1094
+ await worker.loadLanguage("chi_sim");
1095
+ await worker.initialize("chi_sim");
1096
1096
  await worker.setParameters({
1097
- tessedit_char_whitelist: '0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期'
1097
+ tessedit_char_whitelist: "0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期",
1098
1098
  });
1099
1099
  // 识别图像
1100
1100
  const { data } = await worker.recognize(input.imageBase64);
@@ -1107,7 +1107,7 @@
1107
1107
  // 返回处理结果
1108
1108
  return {
1109
1109
  idCardInfo,
1110
- processingTime
1110
+ processingTime,
1111
1111
  };
1112
1112
  }
1113
1113
  catch (error) {
@@ -1128,7 +1128,7 @@
1128
1128
  function parseIDCardText(text) {
1129
1129
  const info = {};
1130
1130
  // 拆分为行
1131
- const lines = text.split('\n').filter(line => line.trim());
1131
+ const lines = text.split("\n").filter((line) => line.trim());
1132
1132
  // 解析身份证号码(最容易识别的部分)
1133
1133
  const idNumberRegex = /(\d{17}[\dX])/;
1134
1134
  const idNumberMatch = text.match(idNumberRegex);
@@ -1137,8 +1137,9 @@
1137
1137
  }
1138
1138
  // 解析姓名
1139
1139
  for (const line of lines) {
1140
- if (line.includes('姓名') || line.length < 10 && line.length > 1 && !/\d/.test(line)) {
1141
- info.name = line.replace('姓名', '').trim();
1140
+ if (line.includes("姓名") ||
1141
+ (line.length < 10 && line.length > 1 && !/\d/.test(line))) {
1142
+ info.name = line.replace("姓名", "").trim();
1142
1143
  break;
1143
1144
  }
1144
1145
  }
@@ -1148,7 +1149,9 @@
1148
1149
  if (genderMatch) {
1149
1150
  info.gender = genderMatch[1];
1150
1151
  const nationalityText = genderMatch[0];
1151
- info.nationality = nationalityText.substring(nationalityText.indexOf(genderMatch[1]) + 1).trim();
1152
+ info.nationality = nationalityText
1153
+ .substring(nationalityText.indexOf(genderMatch[1]) + 1)
1154
+ .trim();
1152
1155
  }
1153
1156
  // 解析出生日期
1154
1157
  const birthDateRegex = /(\d{4})年(\d{1,2})月(\d{1,2})日/;
@@ -1160,19 +1163,19 @@
1160
1163
  const addressRegex = /住址([\s\S]*?)公民身份号码/;
1161
1164
  const addressMatch = text.match(addressRegex);
1162
1165
  if (addressMatch) {
1163
- info.address = addressMatch[1].replace(/\n/g, '').trim();
1166
+ info.address = addressMatch[1].replace(/\n/g, "").trim();
1164
1167
  }
1165
1168
  // 解析签发机关
1166
1169
  const authorityRegex = /签发机关([\s\S]*?)有效期/;
1167
1170
  const authorityMatch = text.match(authorityRegex);
1168
1171
  if (authorityMatch) {
1169
- info.issuingAuthority = authorityMatch[1].replace(/\n/g, '').trim();
1172
+ info.issuingAuthority = authorityMatch[1].replace(/\n/g, "").trim();
1170
1173
  }
1171
1174
  // 解析有效期限
1172
1175
  const validPeriodRegex = /有效期限([\s\S]*?)(-|至)/;
1173
1176
  const validPeriodMatch = text.match(validPeriodRegex);
1174
1177
  if (validPeriodMatch) {
1175
- info.validPeriod = validPeriodMatch[0].replace('有效期限', '').trim();
1178
+ info.validPeriod = validPeriodMatch[0].replace("有效期限", "").trim();
1176
1179
  }
1177
1180
  return info;
1178
1181
  }