Mac原生OCR实操:Monkey see, monkey do 屏幕文字识别工具
2026/8/29 5:55:53 网站建设 项目流程

这次我们来看一个很轻量的 macOS 小项目:Monkey see, monkey do。名字很直白,意思就是“猴子看见什么就做什么”,放到这个项目里就是——用 macOS 原生 OCR 能力,把屏幕上显示的文字原样复现出来

项目思路不复杂,但它踩中了一个很实用的点:macOS 系统自带的 OCR 能力平时被很多人忽略,真正要用的时候又不知道去哪里调。这个项目把它封装成一个可以直接使用的工具,解决的就是“屏幕上这段文字怎么快速复制出来”“PDF 扫描件怎么转成可编辑文本”这类日常问题。

最值得关注的特点是它完全走系统原生框架,不需要额外下载大模型,不需要训练,也不需要 GPU。只要你的 Mac 系统版本够新,基本开箱即用。相比 Tesseract、PaddleOCR 这类需要配置环境的方案,它的部署成本低很多。

这篇文章会用实操视角带你把项目跑起来,内容包括:核心能力梳理、环境要求、部署步骤、功能测试、命令行调用、批量任务思路、资源占用观察和常见问题排查。如果你平时经常处理截图、扫描件、PDF 文档,这篇文章可以直接收藏。

1. 核心能力速览

先看项目的基本信息,方便快速判断它适不适合你。

能力项说明
项目类型macOS 原生 OCR 工具,从屏幕或图片中识别文字并复现
底层能力macOS 系统原生 OCR 框架,非三方模型
主要功能屏幕区域文字识别、图片文字提取、文本复制输出
适合场景截图文字提取、PDF 扫描件复用、屏幕取词、快速整理资料
支持平台macOS,依赖系统版本和硬件兼容性,需按实际环境确认
显存占用无 GPU 依赖,不涉及显存
启动方式命令行启动
是否支持 API可封装为命令行调用,能嵌入脚本流程
是否支持批量任务可以,通过脚本遍历目录完成批量识别
部署难度低,不依赖大体积模型文件

从能力定位来说,它不是一个重型 OCR 服务,而是一个“够用就好”的原生工具。优势在于零模型、零训练、零网络依赖,隐私性也更好,因为识别过程在本地完成。

2. 适用场景与使用边界

2.1 适合谁用

平时需要频繁处理屏幕信息的人最适合这个项目。典型场景包括:

  • 截图文字提取:看到网页、文档、视频里的一段文字,不想手动敲,直接框选识别。
  • PDF 扫描件处理:扫描版 PDF 或图片 PDF 无法直接选取文字,用 OCR 转成文本。
  • 演示文稿资料整理:从网课截图、会议录屏里批量抽取文字。
  • 轻量自动化流程:在 shell 脚本里调用 OCR 命令,自动处理一批图片。
  • 隐私敏感环境:文字内容不想上传到云端 OCR 服务,本地识别更稳妥。

2.2 不适合什么场景

  • 超高精度复杂排版:原生 OCR 对复杂表格、公式、图文混排的还原能力有限。
  • 中文古籍、手写体、生僻字:这类内容识别效果不稳定,需要专门模型。
  • 大规模生产级 OCR:如果要一天处理几十万张图片,原生方案不是最优选择。
  • 跨平台需求:项目绑定 macOS,Windows 和 Linux 需要用其他方案。

2.3 使用边界与合规提醒

屏幕 OCR 本质上是捕捉屏幕上显示的文字内容,使用时要特别注意:

  • 只对自己有权限访问的内容做识别,不要抓取他人设备、非公开聊天记录、加密内容。
  • 涉及商业文档、客户资料、个人隐私信息时,先确认是否有复制和使用权限。
  • 不要用屏幕 OCR 绕过付费内容、版权保护或访问限制。
  • 识别出来的文字如果用于发布、商用或训练,必须核对版权和授权。

这是一个工具,本身没有问题,但怎么用是使用者自己的责任。

3. 环境准备与前置条件

3.1 系统版本

项目依赖 macOS 原生 OCR 能力,所以第一件事是确认系统版本。从项目定位来看,它面向的是较新版本的 macOS,具体最低版本要求没有在源码里标注的话,建议优先在 macOS 12 Monterey 及以上版本测试。更稳妥的判断是:用你的日常系统跑一次,能识别就说明兼容

查看系统版本:

sw_vers

输出类似:

ProductName: macOS ProductVersion: 14.5 BuildVersion: 23F79

如果你的系统版本比较旧,比如 macOS 10.15 或更早,需要先确认原生 OCR 是否可用。部分老版本系统对原生识别框架的支持不完整,可能出现识别结果为空或直接报错。

3.2 开发工具链

项目如果用 Swift 编写,需要安装 Xcode Command Line Tools。打开终端执行:

xcode-select --install

如果已经安装过,会提示“already installed”。

确认 Swift 编译器版本:

swift --version

输出类似:

Apple Swift version 5.9.2

3.3 磁盘空间与内存

这个项目不依赖大型模型文件,磁盘占用很小,主要就是编译产物和临时文件。内存方面,OCR 识别过程会短暂占用一定内存,但不会像大模型推理那样吃满资源。普通 8GB 内存的 Mac 跑起来没有压力。

3.4 权限准备

如果项目需要读取屏幕内容,需要在“系统设置 -> 隐私与安全性 -> 屏幕录制”中把对应的终端应用或 IDE 勾选允许。这一步容易漏,漏了之后识别结果就是空白。

4. 安装部署与启动方式

4.1 获取源码

项目是 GitHub 上常见的工程结构。先克隆到本地:

git clone https://github.com/your-project/monkey-see-monkey-do.git cd monkey-see-monkey-do

注意:这里仓库地址是示例,实际地址以项目页面为准。如果你是从 Show HN 页面进入,直接点击项目链接即可。

4.2 查看项目结构

建议先看一遍目录,确认入口文件、源码文件和说明文件:

ls -la find . -name "*.swift"

常见结构包括:

MonkeySeeMonkeyDo/ ├── Package.swift ├── Sources/ │ └── MonkeySeeMonkeyDo/ │ └── main.swift ├── Tests/ ├── README.md └── .gitignore

4.3 编译与运行

Swift Package Manager 项目可以直接编译:

swift build

编译成功后在.build/debug/目录下会生成可执行文件。运行方式:

swift run MonkeySeeMonkeyDo

如果项目是纯脚本形式,可能直接这样运行:

swift main.swift

第一次编译会下载依赖,耗时取决于网络状况。项目如果依赖少,一般几十秒内能完成。

4.4 配置路径与环境变量

如果项目支持自定义图片路径、输出路径或识别语言,通常会通过命令行参数或者配置文件传入。典型的用法是:

swift run MonkeySeeMonkeyDo --input path/to/image.png --output result.txt

具体参数名需要看 README 或源码中的参数定义。没有明确参数时,先不带参数运行一次,看默认行为是什么。

4.5 验证启动成功

运行后如果出现以下迹象,说明服务或命令正常:

  • 终端输出识别到的文本内容。
  • 指定输出文件生成,内容非空。
  • 没有报错信息。

如果项目会进入监听模式或提供交互界面,终端会显示提示语,比如“Waiting for screenshot”之类。

5. 功能测试与效果验证

5.1 测试素材准备

准备一组不同类型的测试图片,覆盖以下情况:

  • 纯英文截图,字体清晰。
  • 中文截图,区分简体与繁体。
  • 包含数字和标点符号的图片。
  • 屏幕截图,包含窗口标题、菜单栏、正文。
  • 手机拍摄的文档照片。
  • PDF 导出成图片后的页面截图。

建议用系统自带截图工具生成一张:

screencapture -x test.png

这条命令会截取整个屏幕到test.png

5.2 单张图片识别测试

用项目命令对单张图片做识别:

swift run MonkeySeeMonkeyDo --input test.png

预期结果是终端输出图片中所有可识别文字。判断成功的标准:

  • 输出文字和图片内容匹配。
  • 英文单词完整。
  • 中文句子没有明显乱码。
  • 数字和字母识别正确。

如果结果为空,先检查屏幕录制权限,再检查图片清晰度。

5.3 屏幕区域识别测试

有些 OCR 工具支持直接框选屏幕区域。如果项目提供交互模式,运行后按住鼠标拖拽选中区域,松开后自动识别。这种模式更符合“Monkey see, monkey do”的定位——看见哪里,识别哪里。

测试步骤:

  1. 在屏幕上打开一段明显文字,比如一篇新闻网页。
  2. 运行屏幕区域识别命令。
  3. 框选网页正文区域。
  4. 查看输出是否与网页文字一致。

5.4 输出文件测试

如果项目支持输出到文件,可以这样测试:

swift run MonkeySeeMonkeyDo --input test.png --output result.txt cat result.txt

检查文件内容:

  • 文件是否生成。
  • 编码是否为 UTF-8。
  • 内容是否和终端输出一致。
  • 中文是否正常显示,没有乱码。

5.5 识别语言测试

macOS 原生 OCR 通常支持系统语言和常见语言。如果项目支持语言参数,可以尝试:

swift run MonkeySeeMonkeyDo --input chinese.png --language zh-Hans

如果当前系统语言是中文,默认可能已经识别中文。如果不支持中文,需要先确认系统安装了对应的语言支持。

判断标准:

  • 中文句子完整识别。
  • 特殊符号“@”“#”“%”等正确输出。
  • 中英文混排时切换正确。

5.6 失败场景测试

测试几种容易失败的输入:

  • 纯图片、无文字。
  • 模糊截图。
  • 旋转 90 度的文字。
  • 手写文字。
  • 白字黑底反白文字。
  • 带水印背景的半透明文字。

这些场景能帮你了解项目的真实能力边界。原生 OCR 对正常屏幕文字效果好,对复杂背景、艺术字体、手写内容效果会明显下降。

6. 命令行接口与脚本集成

这个项目最有价值的点在于它可以通过命令行调用,能直接嵌入到自动化脚本里。

6.1 命令行参数设计

典型的命令行参数设计可能包括:

--input 输入图片路径 --output 输出文本文件路径 --language 识别语言代码 --region 识别区域,如 "0,0,100,100" --help 显示帮助

没有现成参数文档的话,先运行:

swift run MonkeySeeMonkeyDo --help

查看支持参数。

6.2 单文件处理脚本

写一个简单的 shell 包装脚本,方便反复调用:

#!/bin/bash # ocr_helper.sh - 调用 MonkeySeeMonkeyDo 识别单张图片 INPUT_FILE="$1" OUTPUT_FILE="${2:-result.txt}" if [ -z "$INPUT_FILE" ]; then echo "用法: ./ocr_helper.sh <图片路径> [输出文件]" exit 1 fi swift run MonkeySeeMonkeyDo --input "$INPUT_FILE" --output "$OUTPUT_FILE" if [ $? -eq 0 ]; then echo "识别完成: $OUTPUT_FILE" else echo "识别失败: $INPUT_FILE" >&2 exit 1 fi

保存后加上执行权限:

chmod +x ocr_helper.sh ./ocr_helper.sh test.png output.txt

6.3 Python 调用示例

如果要在 Python 项目里调用,可以用subprocess

import subprocess import sys def ocr_image(image_path, output_path="result.txt"): cmd = [ "swift", "run", "MonkeySeeMonkeyDo", "--input", image_path, "--output", output_path ] result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) if result.returncode != 0: print(f"OCR 识别失败: {result.stderr}") return None with open(output_path, "r", encoding="utf-8") as f: return f.read() if __name__ == "__main__": text = ocr_image(sys.argv[1] if len(sys.argv) > 1 else "test.png") print(text)

运行:

python3 ocr_demo.py test.png

6.4 API 服务封装思路

如果项目本身不提供 HTTP API,也可以自己封装一个轻量服务,把 OCR 能力暴露给局域网内其他工具使用。这里给一个 FastAPI 的通用示例,需要按实际情况调整:

from fastapi import FastAPI, UploadFile, File import subprocess import tempfile import os app = FastAPI() @app.post("/ocr") async def ocr_endpoint(file: UploadFile = File(...)): with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp: tmp.write(await file.read()) tmp_path = tmp.name output_path = tmp_path + ".txt" cmd = [ "swift", "run", "MonkeySeeMonkeyDo", "--input", tmp_path, "--output", output_path ] subprocess.run(cmd, timeout=30) with open(output_path, "r", encoding="utf-8") as f: text = f.read() os.unlink(tmp_path) os.unlink(output_path) return {"text": text}

启动服务:

uvicorn ocr_api:app --host 127.0.0.1 --port 8000

调用:

curl -X POST http://127.0.0.1:8000/ocr \ -H "Content-Type: multipart/form-data" \ -F "file=@test.png"

需要注意,swift run每次调用都会检查编译状态,实际做接口服务时,更合理的方案是直接调用编译后的二进制文件,减少启动开销。

7. 资源占用与性能观察

7.1 观察 CPU 与内存占用

识别过程中可以在另一个终端窗口用top观察:

top -o cpu -l 1

或者用更直观的方式,先开启持续监控:

top -o cpu -n 5

重点看:

  • 识别瞬间 CPU 占用率是否升高。
  • 内存占用是否有明显增长。
  • 识别完成后资源是否回落。

由于不涉及 GPU 和模型推理,资源占用通常很低。如果你观察到内存持续不释放,可能是项目本身存在内存管理问题。

7.2 处理速度观察

单张图片识别速度受以下因素影响:

  • 图片分辨率越高,耗时越长。
  • 图片中文字越多,耗时越长。
  • 系统负载越高,耗时越长。

测试方法:

time swift run MonkeySeeMonkeyDo --input test.png

输出的real时间就是总耗时。如果几十秒甚至几分钟都没有结果,需要检查是否有死循环或权限弹窗等待。

7.3 批量识别性能

批量识别时,如果每次都用swift run启动,会因为编译检查引入额外开销。更高效的做法是编译一次,然后直接调用可执行文件:

swift build -c release ./.build/release/MonkeySeeMonkeyDo --input test.png

这样能明显提高批处理速度。

7.4 如何降低资源占用

  • 识别前先裁剪图片,只保留包含文字的区域。
  • 降低图片分辨率,不需要用 4K 原图。
  • 关闭不必要的后台应用,减少系统负载。
  • 批量任务中控制并发数,避免同时启动太多进程。

8. 常见问题与排查方法

问题现象可能原因排查方式解决方案
运行后无输出屏幕录制权限未开启到系统设置检查权限给终端或 IDE 开启屏幕录制权限
输出乱码图片编码问题或语言不支持换一张标准 PNG 图片测试转换图片格式,检查系统语言支持
中文识别失败系统语言包缺失用英文图片对比测试到系统设置添加中文语言支持
编译报错Swift 版本过旧或依赖缺失执行swift --version安装最新 Xcode Command Line Tools
图片路径找不到路径写错或包含空格检查文件是否存在pwd确认当前目录,路径加双引号
识别结果乱序原生 OCR 对多栏排版支持有限裁剪成单栏图片测试手动裁剪后再识别
批量处理慢每次都重新编译运行查看进程列表编译 release 版本后直接调用二进制
屏幕框选无响应权限弹窗被忽略检查系统设置权限列表重启终端应用后重新授权
输出文件为空图片中没有可识别文字打开图片确认文字可见换一张文字清晰的图片
端口被占用自建 API 服务端口冲突执行lsof -i :8000更换端口号

9. 最佳实践与使用建议

9.1 先跑最小测试

拿到项目后不要直接处理复杂 PDF,先用一张截屏图跑通整个流程,确认权限、编译、输出三个环节都正常。

9.2 建立固定的目录结构

建议保持这样的目录组织:

ocr-workdir/ ├── input/ # 原始图片、截图 ├── output/ # 识别结果文本 ├── logs/ # 运行日志 └── scripts/ # 封装脚本

这样批量任务跑完,结果文件不会散落一地。

9.3 写日志与失败重试

批量处理时,一定要给每个文件记录成功或失败状态。简单做法是在 shell 脚本里追加日志:

echo "$(date) - $INPUT_FILE - SUCCESS" >> logs/ocr.log

失败时:

echo "$(date) - $INPUT_FILE - FAILED" >> logs/ocr_error.log

重试时只处理 error 日志中的文件即可。

9.4 识别后用文本工具二次处理

OCR 出的文本往往存在多余换行、空格错乱、全半角混用问题。可以接一个文本清洗步骤:

cat result.txt | sed 's/ */ /g' > cleaned.txt

更复杂的清洗可以直接在 Python 中做。

9.5 接口服务限制访问

如果你自己封装了 HTTP API,至少要限制在本地访问,不要用0.0.0.0暴露到公网。默认绑定127.0.0.1是最稳妥的方式。

9.6 合规使用提醒

再强调一次:OCR 本身是中立技术,但对他人文档、聊天记录、受版权保护的电子书、付费课程截图进行识别并二次传播,可能涉及版权和隐私问题。请确保你处理的材料是自己有权使用的。

10. 总结与下一步

Monkey see, monkey do 这类项目的价值不在于算法多先进,而在于把 macOS 原生 OCR 能力变成一条可复用的命令。对开发者和效率工具爱好者来说,它提供了几个可以直接用的方向:

  • 把屏幕截图自动转成文字,替代手动抄录。
  • 把 PDF 扫描件批量转成可搜索文本。
  • 在 shell 或 Python 脚本中集成 OCR 能力。
  • 快速验证 macOS 原生 OCR 在自己业务场景下的效果。

建议拿到项目后先完成三件事:编译通过、单图识别成功、命令行参数确认。这三步跑通,后面怎么扩展都顺。

最容易踩的坑是屏幕录制权限没开,导致识别结果始终为空。其次是用swift run跑批量任务太重,编译一次后直接用 release 二进制才是正确做法。

后续可以扩展的方向包括:对接剪贴板实现“截图即识别”、封装成菜单栏小工具、把识别结果自动写入 Obsidian 或 Notion、配合 AppleScript 自动化工作流。

这个项目很适合作为 macOS 效率工具链里的一个基础组件,代码量不大,逻辑清晰,值得拉下来读一遍源码,顺便看看苹果原生 OCR 接口到底怎么调用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询