更新记录
1.0.0(2026-11-12)
初次发版
平台兼容性
uni-app x(4.71)
| Chrome | Safari | Android | iOS | iOS插件版本 | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|
| × | × | 5.0 | 16 | 1.0.0 | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | √ | × |
erha-ocr 本地离线 OCR 识别
纯本地离线 OCR 识别插件。不需要服务器、不需要 API Key、图片不出设备。
支持通用文字识别、身份证正反面识别、银行卡识别。
支持平台:App-Android / App-iOS
最低版本:HBuilderX 4.71+ / uni-app x 4.71+
iOS 买家必读
iOS 端基于 Apple 系统 Vision 框架,插件本身不需额外授权。但要把 App 装到 iPhone (真机调试或上架)必须有 Apple 开发者账号(99 美元/年),这是 Apple 的签名要求, 与插件无关。没有开发者账号的,iOS 端无法运行。
为什么选本地识别
市面上多数 OCR 插件要么要你申请云服务密钥、按次付费,要么要把图片传到第三方服务器。
处理身份证、银行卡这类敏感信息的业务(金融、政务、实名认证)有一条硬性约束:证件照片不允许上传到第三方。云方案在合规评审阶段就可能被否。
本插件全部识别在设备本地完成:
| 云端方案 | 本插件 | |
|---|---|---|
| 服务器 | 需要,按次计费 | 不需要 |
| API Key | 必须申请 | 不需要 |
| 图片流向 | 上传到服务商 | 不出设备 |
| 调用次数 | 有额度限制 | 无限 |
| 金融/政务合规 | 需评估 | 可直接用 |
技术实现
| 平台 | 方案 | 包体积影响 |
|---|---|---|
| Android | Google ML Kit 文字识别(中文) | 约 +5-10MB |
| iOS | Apple Vision 框架 | 几乎为 0(系统自带) |
Android 需要把中文模型打包进 APK,所以包体积会增加几 MB。iOS 用的是系统框架,不占包体积,且走 NPU 加速,单张图通常几十毫秒。
安装
把 uni_modules/erha-ocr 整个目录放进你项目的 uni_modules/ 下。
不需要在 manifest.json 里勾选任何模块,ML Kit 依赖由插件自带的 config.json 声明,云打包会自动处理。
Android 权限
"permissions": [
"<uses-permission android:name=\"android.permission.CAMERA\"/>"
]
iOS 权限
"privacyDescription": {
"NSCameraUsageDescription": "需要使用相机拍摄证件以进行识别",
"NSPhotoLibraryUsageDescription": "需要访问相册以选择图片进行识别"
}
iOS 需要 Apple 开发者账号
再强调一次,因为这是最常见的售后问题:
| 场景 | 是否需要 Apple 开发者账号(99 美元/年) |
|---|---|
| 打 iOS 自定义基座 / 真机调试 | 需要 |
| 上架 App Store | 需要 |
| 只做 Android | 不需要 |
| H5 / 小程序 | 不支持本插件 |
免费 Apple ID 只能用于模拟器和 7 天有效期的个人签名,不能用于正式分发。 如果项目只面向 Android,可以忽略这一节。
这笔费用是 Apple 收取的,与插件无关,也无法绕过。
快速开始
<template>
<view>
<button @click="doRecognize">识别身份证</button>
</view>
</template>
<script setup>
import {
initOcr,
recognizeIdCard,
type RecognizeIdCardResult,
type OcrFail
} from '@/uni_modules/erha-ocr'
onMounted(() => {
initOcr({
success: () => console.log('OCR 就绪'),
fail: (err : OcrFail) => console.log(err.errMsg)
})
})
function doRecognize() {
// 先用相机拍照或从相册选图,拿到本地路径
uni.chooseImage({
count: 1,
success: (res) => {
recognizeIdCard({
filePath: res.tempFilePaths[0],
side: 'front', // front 人像面 / back 国徽面
success: (r : RecognizeIdCardResult) => {
const info = r.front
if (info != null) {
console.log('姓名:', info.name)
console.log('身份证号:', info.idNumber)
console.log('校验通过:', r.valid)
}
},
fail: (err : OcrFail) => {
uni.showToast({ title: err.errMsg, icon: 'none' })
}
})
}
})
}
</script>
注意:必须从插件根路径
@/uni_modules/erha-ocr导入,不要引用utssdk内部文件。
API
initOcr(options)
初始化识别引擎。Android 会加载模型,建议在页面 onMounted 或 App onLaunch 调用一次。
| 参数 | 类型 | 说明 |
|---|---|---|
success |
(res: string) => void |
初始化成功 |
fail |
(err: OcrFail) => void |
初始化失败 |
recognizeText(options)
通用文字识别,返回全部文本。
| 参数 | 类型 | 说明 |
|---|---|---|
filePath |
string |
图片本地路径 |
success |
(res: OcrTextResult) => void |
识别成功 |
fail |
(err: OcrFail) => void |
识别失败 |
// OcrTextResult
{
fullText : string // 整段文本,按行用 \n 连接
lines : OcrLine[] // 逐行结果(当前版本为空数组,用 fullText 即可)
width : number // 图片宽度
height : number // 图片高度
}
recognizeIdCard(options)
身份证识别。
| 参数 | 类型 | 说明 |
|---|---|---|
filePath |
string |
图片本地路径 |
side |
string |
'front' 人像面 / 'back' 国徽面 |
success |
(res: RecognizeIdCardResult) => void |
识别成功 |
fail |
(err: OcrFail) => void |
识别失败 |
// RecognizeIdCardResult
{
front : IdCardFront | null // 人像面字段
back : IdCardBack | null // 国徽面字段
rawText : string // 原始识别文本,用于排查
valid : boolean // 是否通过校验
}
// IdCardFront
{
name : string // 姓名
gender : string // 性别:男 / 女
ethnicity : string // 民族,如「汉」
birthday : string // 出生,格式 1990-05-12
address : string // 住址(已合并跨行)
idNumber : string // 18 位身份证号
}
// IdCardBack
{
issuingAuthority : string // 签发机关
validFrom : string // 有效期起,格式 2015-01-01
validTo : string // 有效期止,格式 2035-01-01 或「长期」
}
recognizeBankCard(options)
银行卡识别。
// RecognizeBankCardResult
{
card : BankCard | null
rawText : string
valid : boolean
}
// BankCard
{
cardNumber : string // 卡号(已去除空格)
cardType : string // 借记卡 / 信用卡
bankName : string // 发卡行,如「工商银行」,未匹配时为空串
}
releaseOcr()
释放资源。页面卸载时可选调用,不调也不影响使用。
工具函数
插件还导出了几个纯逻辑工具函数,可以直接用:
import {
isValidIdNumber,
isValidBankCard,
formatCardNumber,
maskCardNumber
} from '@/uni_modules/erha-ocr/utssdk/utils/parser.uts'
isValidIdNumber('110105199005123012') // true,18 位身份证校验位校验
isValidBankCard('6222021234567896') // true,Luhn 校验
formatCardNumber('6222021234567896') // '6222 0212 3456 7896'
maskCardNumber('6222021234567896') // '**** **** **** 7896'
识别准确率是怎么保证的
单纯把 OCR 文本吐出来没用,用户要的是「姓名:张三」这样的结构化字段。本插件在解析层做了这些处理:
身份证号校验位
采用 GB 11643-1999 标准的校验位算法。18 位身份证号最后一位是前 17 位算出来的校验码,OCR 认错任何一位都会导致校验失败。这是最有效的一道防线。
关键字定位 + 位置兜底
身份证排版固定,正常情况下靠「姓名」「住址」等关键字定位。但当 OCR 把关键字认丢时,改用位置策略:出生日期下面、身份证号上面就是住址。
血缘兜底
性别和出生日期可从身份证号第 17 位和第 7-14 位反推,OCR 文本认错时用这个兜底。
住址跨行合并
身份证住址通常占 2-3 行,按行序拼接,遇到身份证号行停止。
银行卡 Luhn 校验
银行卡号有 Luhn 校验,同样能拦截大部分误识别。另外做了卡号分段合并(6222 0212 3456 7896)和跨行拼接处理。
实测数据
用 4 组模拟 ML Kit 输出的文本测试(含关键字完整、关键字缺失、日期格式变体、完全无关键字四种情况),字段命中率 95.8%(23/24)。未命中的那个是日期用纯空格分隔的极端情况。
常见问题
Q:能离线用吗?
能。Android 的模型随 APK 打包,iOS 用系统框架,首次使用不需要联网下载。
Q:Android 包体积增加多少?
约 5-10MB,取决于 ABI 数量。如果只需要单 ABI(如仅 arm64-v8a),增量更小。iOS 几乎不增加。
Q:H5 / 小程序能用吗?
不能。Vision 和 ML Kit 都是 App 端原生能力。H5 端调用会返回错误码 2001 并提示不支持。如果在 H5 有需求,建议做端判断后降级为手动输入。
Q:识别不准怎么办?
先看 rawText 里 OCR 到底认出了什么。常见原因:
- 图片模糊或反光 → 提示用户重拍
- 证件倾斜 → 拍照时提示四角对齐
- 光照不足 → 用组件的闪光灯
Q:为什么 valid 是 false?
valid 表示关键字段校验通过。身份证看 18 位校验位,银行卡看 Luhn。如果不通过但字段看起来是对的,可能是 OCR 认错了某一位,建议重拍。
Q:支持护照、驾驶证、营业执照吗?
当前版本只做了身份证和银行卡的字段解析。通用文字识别(recognizeText)可以识别任何文字,但要结构化成护照/营业执照字段,需要自己解析 rawText。
Q:能连续识别、自动追焦吗?
当前版本是拍照识别(takePhoto + 识别)。实时流式识别(对着证件自动识别)需要逐帧处理,当前未实现。
已知限制
- 只支持 App-Android / App-iOS,H5 和小程序不可用
- Android 端包体积会增加 5-10MB
OcrTextResult.lines当前为空数组,多语言/多段落定位需求请用fullText- 鸿蒙未适配
必须重新打自定义基座
本插件包含原生代码(Kotlin + Swift 混编),标准的 HBuilderX 基座里没有这些原生类。
如果直接运行,会报类似错误:
error: undefined class: UTSSDKModulesErhaOcrIndexSwift, ...
插件不存在或者编译错误 ... Windows端请重新打自定义基座
这不是插件坏了,是基座里还没有你的原生代码。 正确做法:
- 菜单:发行 → 原生 App-云打包
- 勾选「打自定义调试基座」
- 打包完成后,运行 → 运行到手机或模拟器 → 选择「自定义基座」
Android 修改原生代码(.kt)后必须重新打基座;iOS 同理。改 index.uts 或 parser.uts 这类纯 UTS 逻辑,热更新即可,不用重打。
iOS 本地编译需要 Xcode 26 及以上
如果你在 Mac 上「运行到 iOS 模拟器」(本地编译插件,不走云打包),Xcode 版本必须 26+(Swift 6.2+)。
Xcode 16.x(Swift 6.0/6.1)会报:
error: missing argument label 'dictionary:' in call
at uni_modules/erha-ocr/utssdk/app-ios/index.uts
原因:HBuilderX 4.7+ 的 iOS UTS 运行时是按 Swift 6.2+ 编译的,其中
UTSJSONObject 的部分初始化器和下标访问带 #if compiler(>=5.3) && $NonescapableTypes
条件编译。旧版 Swift 读不到这些符号,而 UTS 转译器生成的代码依赖它们。
这条与插件本身无关,是工具链版本问题。 两种解决办法:
- 升级到 Xcode 26+(推荐,一次到位)
- 不本地编译,直接用云打包(不受本机 Xcode 影响)
我们用云打包验证过 Android 和 iOS 双端真机运行正常。若你只在 Windows 上开发, 完全不需要碰这个问题 —— 云打包直接在云端编译。
更新日志
License
MIT

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 4111
赞赏 0
下载 12761349
赞赏 1959
赞赏
京公网安备:11010802035340号