OCR 文字识别 — ML Kit 与 Paddle Lite 双引擎
引擎选型
AutoJs6 的 OCR 特性基于 Google ML Kit 和 Baidu PaddlePaddle(Paddle Lite)两个引擎实现:
| 引擎 | 模型 | 特点 | 适用场景 |
|---|---|---|---|
| ML Kit | Google 官方 | 轻量、快速、支持多种语言 | 快速识别、简单文字 |
| Paddle Lite | PP-OCRv5 | v6.7 新增,精度更高,中文效果好 | 需要高精度的中文识别 |
切换引擎
// 查看当前工作模式
console.log("当前模式: " + ocr.mode);
// 切换到 Paddle Lite(更精准)
ocr.mode = "paddle";
// 切换到 ML Kit(更快)
ocr.mode = "mlkit";
基本用法
detect — 识别全部文字
let screen = images.captureScreen();
// 识别图片中的所有文字
let result = ocr.detect(screen);
console.log("识别到的文本: " + result.text);
console.log("识别到 " + result.results.length + " 个文本块");
screen.recycle();
识别结果结构
let result = ocr.detect(screen);
// result 结构示例
{
text: "总文本内容",
results: [
{
text: "价格: ¥99",
bounds: Rect { left, top, right, bottom },
confidence: 0.95 // 置信度 0-1
},
{
text: "立即购买",
bounds: Rect { left, top, right, bottom },
confidence: 0.92
}
]
}
区域识别
// 只识别屏幕下半部分
let screen = images.captureScreen();
let cropped = images.clip(screen, 0, 960, 1080, 960); // 下半屏
let result = ocr.detect(cropped);
console.log("下半屏文字: " + result.text);
cropped.recycle();
screen.recycle();
指定语言识别
// ML Kit 支持指定识别语言
ocr.mode = "mlkit";
// 中文
let result = ocr.detect(screen, { language: "zh-CN" });
// 英文
let result = ocr.detect(screen, { language: "en" });
// 多语言
let result = ocr.detect(screen, { language: "zh-CN,en" });
实战:基于 OCR 点击文字
/**
* 在屏幕上找到包含"立即购买"的区域并点击
*/
function clickByOcr(targetText) {
let screen = images.captureScreen();
let result = ocr.detect(screen);
let found = null;
for (let block of result.results) {
if (block.text.includes(targetText)) {
found = block;
break;
}
}
screen.recycle();
if (found) {
// 点击文字区域的中心
let bounds = found.bounds;
let cx = (bounds.left + bounds.right) / 2;
let cy = (bounds.top + bounds.bottom) / 2;
click(cx, cy);
toast("已点击: " + found.text);
return true;
}
toast("OCR 未找到: " + targetText);
return false;
}
// 使用
clickByOcr("立即购买");
clickByOcr("确认订单");
结合选择器使用
很多时候 OCR 和控件选择器配合效果更好:
// 场景:遍历商品列表,找到价格低于 100 的
function findCheapItems() {
let screen = images.captureScreen();
let result = ocr.detect(screen);
screen.recycle();
let cheapPositions = [];
// 用 startsWith 代替正则字符类,避免 md 内链误判
result.results.forEach(block => {
let text = block.text;
let price = null;
// 提取价格:先找货币符号
let yenIdx = text.indexOf("¥");
let yuanIdx = text.indexOf("¥");
let symbolIdx = Math.max(yenIdx, yuanIdx);
if (symbolIdx >= 0) {
// 从货币符号后提取数字
let after = text.substring(symbolIdx + 1);
let match = after.match(/^(\d+)/);
if (match) {
price = parseInt(match[1]);
}
}
if (price !== null && price < 100) {
let bounds = block.bounds;
cheapPositions.push({
x: (bounds.left + bounds.right) / 2,
y: (bounds.top + bounds.bottom) / 2,
price: price
});
}
});
console.log("找到 " + cheapPositions.length + " 件低价商品");
return cheapPositions;
}
OCR 插件(v6.7)
v6.7 新增 Paddle OCR(PP-OCRv5)作为独立插件:
- 可在插件中心单独安装 / 更新
- 插件中心入口:主页抽屉按钮 / 主页标签页
- 不同插件版本可灵活切换
性能注意
速度对比
| 引擎 | 速度(全屏识别) | 内存占用 |
|---|---|---|
| ML Kit | 约 1-3 秒 | 较低 |
| Paddle Lite | 约 3-8 秒 | 较高 |
加速技巧
// ✅ 剪裁后再识别(大幅提速)
let cropped = images.clip(screen, x, y, w, h);
ocr.detect(cropped);
cropped.recycle();
// ❌ 不要:循环中反复全屏 OCR
while (true) {
let screen = images.captureScreen();
ocr.detect(screen); // 每次都全图识别,很慢
screen.recycle();
sleep(2000);
}
内存压力
OCR 模块在低内存设备(< 4GB RAM)上可能被系统回收,表现为脚本意外停止。建议:
- 尽量用区域剪裁减少识别范围
- 避免循环中连续调用 OCR
- 及时 recycle 截图 Image 对象
OCR 适用场景
| 场景 | 推荐度 | 说明 |
|---|---|---|
| 游戏界面文字 | ⭐⭐⭐⭐ | 游戏控件树不可读,OCR 是唯一方案 |
| WebView H5 页面 | ⭐⭐⭐ | H5 内部控件不可读,OCR 替代 |
| 无 id/text 的原生 App | ⭐⭐⭐⭐ | 补充选择器的不足 |
| 图片文字提取 | ⭐⭐⭐⭐⭐ | 从图片中提取信息 |
| 纯文本内容查找 | ⭐⭐⭐⭐ | 结合 bounds 点击 |
局限性
- 非实时:OCR 需要截图 → 识别两步,无法实现毫秒级响应
- 受清晰度影响:模糊、倾斜的文字识别率下降
- 性能开销:比控件选择器慢很多,不能高频调用
- 背景干扰:复杂背景下可能误识别