每天打开电脑,需求很简单:把一张图里的文字抠出来。
但写过的人都知道这事并不简单:
结果就是:一个 OCR 功能,三端三套代码,加上云端能扩到第四套。
uniOCR 就是为了这件事而生的——一个 Rust crate,把上面这些底层差异全部封进同一个 OcrEngine 接口。你写一次代码,三端跑通,云端切换只换枚举值。
今天这篇,给你 6 个使用要点,照着做就能跑。

uniOCR 跨平台架构示意
先把它放进表格里,避免选型踩坑:
维度 | uniOCR | Tesseract 直调 | 云端 OCR API |
|---|---|---|---|
跨平台 | ✅ macOS/Win/Linux | ✅ 但要装环境 | ✅ 但要联网 |
离线能力 | ✅ 原生引擎离线 | ✅ | ❌ |
调用语言 | Rust 一行代码 | C++/绑定层 | HTTP/SDK |
平均速度(M4 Max) | 1.2–3.2 张/秒 | 视模型而定 | 受网络制约 |
上手成本 | 加一行 Cargo 依赖 | 装库+编译 | 注册+鉴权 |
一句话总结:本地优先、跨平台、Rust 原生,适合放进客户端、桌面 Agent、Screenshot pipeline。
打开你的 Cargo.toml,在 [dependencies] 下加一行:
[dependencies]
uni-ocr = { git = "https://github.com/mediar-ai/uniocr.git" }
tokio = { version = "1", features = ["full"] }
anyhow = "1"注意两点:
uni-ocr(中划线),import 时是 uniocr(无连字符),别写错最小可运行示例,复制即用:
use uniocr::{OcrEngine, OcrProvider};
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
let engine = OcrEngine::new(OcrProvider::Auto)?;
let text = engine.recognize_file("path/to/image.png").await?;
println!("extracted text: {}", text);
Ok(())
}关键点:
OcrProvider::Auto 会自动挑当前系统最快的引擎(macOS → Vision,Windows → Win OCR,Linux → Tesseract)async,方便嵌进现有异步管线String,不用再解析中间结构如果你只是想"识别一张图",到这里就结束了。下面的要点是给真要把它放进生产代码的人看的。
Auto 适合 demo,但生产环境建议显式指定:
// 强制走 macOS 原生 Vision(精度 90%,速度 3.2 张/秒)
let engine = OcrEngine::new(OcrProvider::MacOS)?;
// 强制走 Windows 原生引擎(精度 95.2%,速度 1.2 张/秒)
let engine = OcrEngine::new(OcrProvider::Windows)?;
// 跨平台保底:走 Tesseract
let engine = OcrEngine::new(OcrProvider::Tesseract)?;选型口诀:

Provider 选型决策图
OcrOptions 调优识别效果光会喊"识别"不够,真实业务里你要做的事是:
uniOCR 给了一套链式 API:
use uni_ocr::{OcrEngine, OcrProvider, OcrOptions};
let options = OcrOptions::default()
.languages(vec!["eng", "fra"])
.confidence_threshold(0.8)
.timeout(std::time::Duration::from_secs(30));
let engine = OcrEngine::new(OcrProvider::Auto)?
.with_options(options);经验值参考:
场景 | 推荐 confidence | 备注 |
|---|---|---|
截图笔记 | 0.6–0.7 | 容忍小错,召回优先 |
表格/数字 | 0.85+ | 错一个数据就完蛋 |
多语言混排 | 0.7 | 配合 languages() 列举 |
recognize_batch,别自己写循环如果你一次要处理 N 张图(典型场景:屏幕录制后切帧、PDF 页转图),别 for 循环 + await:
let images = vec!["img1.png", "img2.png", "img3.png"];
let results = engine.recognize_batch(images).await?;recognize_batch 内部做了并行调度,根据 README 说法是"async/await + parallel processing + memory efficient",并强调了"unsafe 部分是经过内存泄漏压力测试的"。
实测建议:
很多人第一次跑出错,不是代码问题,是环境没装齐。一份对照清单:
平台 | 是否需要额外安装 | 命令 |
|---|---|---|
macOS | 不需要(系统自带 Vision Kit) | —— |
Windows 10+ | 不需要(系统自带 OCR) | —— |
Tesseract / Linux | 需要 | apt-get install tesseract-ocr |
Tesseract / macOS | 需要 | brew install tesseract |
Tesseract / Windows | 需要 | winget install tesseract |
⚠️ 用 Tesseract 时记得装语言包(中文要 tesseract-ocr-chi-sim,否则识别中文一团乱码)。

三端依赖安装速查表
仓库里给出的 benchmark 是在 M4 MacBook Pro Max 上跑的(单位:images/second):
Provider | 速度 | 精度 |
|---|---|---|
macOS Vision | 3.2 | 90.0% |
Windows OCR | 1.2 | 95.2% |
Tesseract | TBD | TBD |
Google Cloud | TBD | TBD |
读这张表的正确姿势:
cargo run --example basic仓库 examples/ 目录提供了 4 个 ready-to-run 程序:
# 1. 基础:单张识别
cargo run --example basic
# 2. 批量:多张并行
cargo run --example batch_processing
# 3. 选项:自定义参数
cargo run --example custom_options
# 4. 平台:强制指定 provider
cargo run --example platform_specific推荐学习路径:
basic,确认环境 OKcustom_options,理解 OcrOptions 的链式调用batch_processing 的并发结构platform_specific 处理 cfg 分支最后给一份选型 checklist,避免你装回去又删掉:
值得引入:
不值得引入:
把今天这篇浓缩成 6 行,可以截图保存:
uni-ocr (git) + tokio + anyhow,一次到位OcrEngine::new(Auto) + recognize_file() 三行跑通recognize_batch 自带并行从今天开始,先做第一步:在你 next 的 Rust 小项目里把这一行加进去:
uni-ocr = { git = "https://github.com/mediar-ai/uniocr.git" }跑通 basic 例子,再考虑要不要替换掉你已有的 OCR 调用。
项目地址:https://github.com/screenpipe/uniOCR 截至 2026 年 6 月:Star 224 / Fork 20 / 主语言 Rust / License MIT
如果你有更好的跨平台 OCR 方案,或者用 uniOCR 做出了有意思的项目,欢迎在评论区告诉我。
今天的分享就到这里。后续我会持续为大家带来实用的技术干货和前沿的技术资讯。如果你对工具链探索感兴趣,我会持续分享前端工程化、构建优化等实战经验,欢迎关注,不要错过任何精彩内容!