更新记录

1.0.0(2026-11-04)

更新日志

[1.0.0] - 2026-11-03


平台兼容性

uni-app(5.33)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- √ √ √ √ - √ √ -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(5.33)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - - -

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
√ × √ ×

uni-ocr 插件使用文档

基于 Tesseract.js (WebAssembly) 的纯前端 OCR 插件,一套代码兼容 H5 / App (Android/iOS) / 微信小程序。

目录


安装

依赖

npm install tesseract.js@^5.1.0

引入

将 sys-uni-ocr/ 整个目录复制到你的 uni-app 项目的 uni_modules/ 目录下即可:

your-project/
├── uni_modules/
│   └── sys-uni-ocr/      ← 整个目录拷贝进来

快速上手

方式一:useOcr Hook(推荐)

<template>
  <view>
    <!-- 状态徽标 -->
    <view v-if="initializing">加载中...</view>
    <view v-else-if="initialized">就绪</view>
    <view v-else-if="hasError">加载失败</view>

    <!-- 识别按钮 -->
    <button :disabled="initialized && !loading" @tap="pickAndRecognize">
      选择图片并识别
    </button>

    <!-- 结果 -->
    <view v-if="text" class="result">
      识别结果:{{ text }}
      置信度:{{ confidence }}%
    </view>
  </view>
</template>

<script setup>
import { computed } from 'vue'
import { useOcr, chooseImage } from '@/uni_modules/sys-uni-ocr'

const {
  loading,           // 是否正在识别
  initializing,      // 是否正在初始化引擎
  initialized,       // 引擎是否已就绪
  progress,          // 进度 0-1
  progressStatus,    // 当前进度描述
  text,              // 识别出的纯文本 (computed)
  confidence,        // 整体置信度 (computed)
  error,             // 错误信息
  recognize,         // 手动识别方法
  destroy,           // 释放资源
} = useOcr({
  languages: ['chi_sim', 'eng'],
  autoInit: true,
  autoTerminate: false
})

const hasError = computed(() => !initialized.value && !initializing.value && !!error.value)

async function pickAndRecognize() {
  const pickResult = await chooseImage({ sourceType: ['album'] })
  if (pickResult?.tempFilePath) {
    const result = await recognize(pickResult.tempFilePath)
    console.log('识别完成:', result)
  }
}
</script>

方式二:OcrScanner 组件(开箱即用)

<template>
  <view>
    <OcrScanner
      :languages="['chi_sim', 'eng']"
      :autoRecognize="false"
      @success="handleOcrResult"
      @error="handleOcrError"
    />
  </view>
</template>

<script setup>
import OcrScanner from '@/uni_modules/sys-uni-ocr/components/sys-uni-ocr/sys-uni-ocr.vue'

function handleOcrResult(result) {
  console.log('识别文本:', result.text)
  console.log('置信度:', result.confidence)
  console.log('按行:', result.lines)
}

function handleOcrError(err) {
  uni.showToast({ title: err.message, icon: 'none' })
}
</script>

方式三:一行代码

import { quickRecognize } from '@/uni_modules/sys-uni-ocr'

const result = await quickRecognize('/path/to/image.jpg', {
  languages: ['chi_sim', 'eng']
})
console.log(result.text)

API 参考

useOcr(options?)

核心 Hook,返回 OCR 状态、计算属性和方法。

返回值(Ref)

名称 类型 说明
result Ref<OcrResult \| null> 原始识别结果对象
loading Ref<boolean> 是否正在识别(识别阶段)
initializing Ref<boolean> 是否正在初始化引擎(不阻塞 UI)
progress Ref<number> 当前进度 0 - 1
progressStatus Ref<string> 进度描述文本,如 "加载语言模型..."
error Ref<Error \| null> 错误信息
available Ref<boolean \| null> 引擎可用性检查结果
initialized Ref<boolean> 引擎是否已就绪

返回值(Computed)

名称 类型 说明
text ComputedRef<string> 识别出的纯文本
confidence ComputedRef<number> 整体置信度 (0-100)
lines ComputedRef<LineResult[]> 按行分割的结果
words ComputedRef<WordResult[]> 按单词/词组分割的结果
isSuccess ComputedRef<boolean> 是否识别成功
hasError ComputedRef<boolean> 是否有错误

返回值(方法)

方法 签名 说明
init() () => Promise<boolean> 手动初始化 Worker(默认 autoInit=true)
recognize(image, overrides?) (string \| ImageData, object?) => Promise<OcrResult> 识别单张图片,未初始化时会自动 init
recognizeFromAlbum(opts?) (object?) => Promise<OcrResult \| null> 从相册选图并识别(一步到位)
recognizeFromCamera(opts?) (object?) => Promise<OcrResult \| null> 拍照并识别(一步到位)
batchRecognize(images, overrides?) (string[], object?) => Promise<OcrResult[]> 批量识别多图
changeLanguages(languages) (string[]) => Promise<boolean> 切换语言(自动重建 Worker)
checkAvailability() () => Promise<{available, platform, reason?}> 检查当前环境是否支持
clearResult() () => void 清空当前结果
destroy() () => Promise<void> 释放 Worker 资源

OcrResult 结构

{
  text: '识别出的完整文本',
  confidence: 98.5,          // 整体置信度 (0-100)
  isSuccess: true,
  lines: [
    { text: '第一行', confidence: 97, boundingBox: { x0, y0, x1, y1 } }
  ],
  words: [
    { text: 'word', confidence: 99, boundingBox: { ... } }
  ],
  symbols: [ /* ... */ ],
  boxes: [ /* 文本块 */ ],
  rawData: { /* Tesseract 原始返回 */ }
}

chooseImage(options)

跨平台图片选择,适配 H5 / App / 小程序。

import { chooseImage } from '@/uni_modules/sys-uni-ocr'

const result = await chooseImage({
  sourceType: ['album'],     // 'album' | 'camera' | ['album', 'camera']
  count: 1,
  sizeType: ['compressed']   // 'original' | 'compressed'
})
// result: { tempFilePath: '...', tempFilePaths: ['...'] }

配置项

useOcr 选项

useOcr({
  // 识别语言(支持多语言组合)
  languages: ['chi_sim', 'eng'],

  // OCR 引擎模式
  oem: OEM_MODES.LSTM_ONLY,   // 1 = 仅 LSTM(推荐)

  // 页面分割模式
  psm: PSM_MODES.AUTO,        // 3 = 自动检测

  // 是否启用图像预处理
  preprocess: false,
  preprocessSteps: ['grayscale', 'binarize'],

  // Worker 路径配置(全部可选,有默认值)
  workerOptions: {
    workerPath: '',     // Worker JS 路径
    corePath: '',       // wasm JS 路径
    langPath: '',       // 语言包根目录
    methodPath: ''      // Worker 方法路径
  },

  // 是否自动初始化(页面加载时开始下载引擎)
  autoInit: true,

  // 识别后组件卸载时是否自动释放
  autoTerminate: false,

  // 进度回调
  onProgress: (info) => {
    console.log(info.status, info.progress)
  }
})

OcrScanner Props

<OcrScanner
  :languages="['chi_sim', 'eng']"
  :sourceType="'both'"        <!-- 'album' | 'camera' | 'both' -->
  :showSelection="true"       <!-- 是否显示四角选择框 -->
  :autoRecognize="false"      <!-- 选图后是否自动识别 -->
  :maxWidth="1280"            <!-- 图片最大宽度(未实现) -->
  :maxHeight="1280"           <!-- 图片最大高度(未实现) -->
  @success="handleResult"
  @error="handleError"
  @pick="handlePick"
/>

内置常量

import { OEM_MODES, PSM_MODES } from '@/uni_modules/sys-uni-ocr'

// 引擎模式
OEM_MODES.TESSERACT_ONLY    // 0
OEM_MODES.LSTM_ONLY         // 1  ← 推荐
OEM_MODES.TESSERACT_LSTM    // 2
OEM_MODES.DEFAULT           // 3

// 页面分割模式
PSM_MODES.OSD_ONLY          // 0
PSM_MODES.AUTO_OSD          // 1
PSM_MODES.AUTO              // 3  ← 推荐
PSM_MODES.SINGLE_BLOCK      // 6
PSM_MODES.SINGLE_WORD       // 8

多端说明

平台 支持 wasm 说明
H5 ✅ ✅ WebAssembly 完整功能,CDN 加载
App (Android) ✅ ✅ WebView wasm 完整功能
App (iOS) ✅ ✅ WebView wasm 完整功能
微信小程序 ⚠️ 受限 ⚠️ 基础库 ≥ 2.19.0 wasm 兼容性有限

CDN 策略

默认使用 jsDelivr CDN(国内加速):

资源 URL
Worker https://cdn.jsdelivr.net/npm/tesseract.js@5.1.0/dist/worker.min.js
Core https://cdn.jsdelivr.net/npm/tesseract.js-core@5.1.0/tesseract-core-simd.wasm.js
语言包 https://cdn.jsdelivr.net/gh/naptha/tessdata@gh-pages/4.0.0/{lang}.traineddata.gz

本地化部署(推荐生产使用)

将 wasm + 语言包下载到 static/ 目录:

static/
├── tesseract-core-simd.wasm.js
├── worker.min.js
├── eng.traineddata.gz
└── chi_sim.traineddata.gz

配置本地路径:

useOcr({
  languages: ['chi_sim', 'eng'],
  workerOptions: {
    corePath: '/static/tesseract-core-simd.wasm.js',
    langPath: '/static/'
  }
})

这样首次识别零网络依赖、毫秒级初始化。


常见问题

Q1: 页面一直显示"加载中..."怎么办?

现象: 徽标卡在"加载 OCR 引擎..."不变化,持续超过 120 秒。

原因: 网络无法访问 jsDelivr CDN(极少数公司内网)。

解决方案: 将 wasm + 语言包本地化(见上方"本地化部署")。

Q2: 如何只识别英文?

useOcr({ languages: ['eng'] })

Q3: 微信小程序里为什么没反应?

微信小程序需要基础库 ≥ 2.19.0 才支持 WebAssembly。可在 manifest.json 里确认。

Q4: 识别不准确怎么办?

  1. 保证图片清晰度 — 建议上传清晰图片,不要截图或压缩过度
  2. 调整 PSM 模式 — 长文档用 PSM_MODES.AUTO,单文本行用 PSM_MODES.SINGLE_WORD
  3. 增加语言 — 如果图片中英混合,务必传 ['chi_sim', 'eng']

Q5: 如何释放资源?

组件卸载时如果配置了 autoTerminate: true 会自动释放。也可以手动调用:

onUnmounted(() => {
  destroy()
})

Q6: 支持哪些语言?

所有 Tesseract 4.x 训练好的语言包,完整列表: https://github.com/naptha/tessdata/tree/gh-pages/4.0.0

常用:eng 英文、chi_sim 中文简体、chi_tra 中文繁体、jpn 日文、kor 韩文。


架构图

┌─────────────────────────────────────────────────┐
│                  useOcr Hook                     │
│  ┌─────────┐ ┌──────────┐ ┌──────────────────┐  │
│  │ 状态     │ │ 计算属性  │ │ 方法 (recognize) │  │
│  └────┬────┘ └────┬─────┘ └──────┬───────────┘  │
└───────┼───────────┼──────────────┼──────────────┘
        │           │              │
        ▼           ▼              ▼
┌─────────────────────────────────────────────────┐
│            tesseract-engine.js                   │
│  ┌─────────────────────────────────────────┐    │
│  │  Tesseract.createWorker (单例)           │    │
│  │  ┌─────────────────────────────────┐    │    │
│  │  │ Web Worker + WebAssembly (SIMD) │    │    │
│  │  └─────────────────────────────────┘    │    │
│  └─────────────────────────────────────────┘    │
└─────────────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────────┐
│              平台适配层 (adapters/)               │
│  h5-adapter  │  app-adapter  │  mp-adapter      │
└─────────────────────────────────────────────────┘

更新日志

详见 CHANGELOG.md。

License

MIT

隐私、权限声明

1. 本插件需要申请的系统权限列表:

相机权限(拍照识别)、相册权限(选图识别)、网络权限(首次加载OCR引擎)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

不采集用户数据,所有识别在本地完成

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。