This commit is contained in:
王鹏
2026-04-09 14:55:54 +08:00
commit a2f5875d1b
60 changed files with 5210 additions and 0 deletions

81
docs/plan.md Normal file
View File

@@ -0,0 +1,81 @@
这是一个非常明智的选择。**Umi-OCR** 相比于直接调用 `PaddleOCR` 的库,最大的优势在于它提供了一个非常成熟的 **HTTP API 接口**(或者离线命令行接口),这使得你的 Python 自动化脚本可以保持轻量化,不需要在本地环境安装庞大且容易起冲突的深度学习库。
以下是针对 **Umi-OCR** 集成的更新版开发指南 MD 文档:
---
# 🚀 桌面自动化脚本开发指南 (Umi-OCR 集成版)
## 1. 系统架构说明
本脚本采用 **Umi-OCR (HTTP 服务模式)** 作为感知核心。脚本通过发送截图到 Umi-OCR 的本地 API获取 JSON 格式的识别结果(文字内容及坐标)。
---
## 2. 核心技术栈
* **OCR 引擎**: [Umi-OCR](https://github.com/hiroi-sora/Umi-OCR) (需提前启动 HTTP 服务)。
* **浏览器控制**: Playwright (用于操作 Web 端 DMS/ERP)。
* **桌面控制**: PyAutoGUI / Mouse (用于点击 OCR 识别出的坐标)。
* **通信**: `requests` (用于调用 Umi-OCR API)。
---
## 3. 目录结构规范
```text
project_root/
├── config/ # 配置文件 (yaml/json)
├── core/
│ ├── ocr_client.py # 封装 Umi-OCR API 调用逻辑
│ ├── browser.py # Playwright 页面操作
│ └── actions.py # 封装“识别文字并点击”的高级动作
├── config.yaml # 存放 Umi-OCR 地址 (默认 http://127.0.0.1:1224/api/ocr)
├── data/ # 存放临时截图、下载的文件
├── assets/ # 存放用于识别的图标/模板图片
├── utils/ # 日志、时间处理等工具类
└── main.py # 业务主流程
```
---
## 4. 关键模块开发逻辑
### 4.1 OCR 调用逻辑 (`ocr_client.py`)
> **AI 指令**:请实现一个 `UmiClient` 类,要求:
* 使用 `requests``http://127.0.0.1:1224/api/ocr` 发送 Base64 编码的图片。
* 解析返回的 JSON提取 `data` 列表中的 `text``box`(四个顶点的坐标)。
* 提供一个 `find_text(target_name)` 方法,返回该文字在屏幕上的中心点 `(x, y)`
### 4.2 自动化执行逻辑 (`actions.py`)
> **AI 指令**:结合 `PyAutoGUI` 和 `ocr_client.py`
* 实现 `click_text(text)`:截图 -> OCR 识别 -> 匹配目标 -> 点击。
* 实现 `wait_for_text(text, timeout=20)`:在规定时间内循环检测屏幕是否出现目标文字。
---
## 5. 开发约束
1. **服务检测**:脚本启动时需检测 Umi-OCR 端口是否占用,若未启动则抛出错误提醒。
2. **区域 OCR**:为了提高效率,支持“局部截图 OCR”而不是每次都截全屏。
3. **坐标转换**Umi-OCR 返回的是相对图片的坐标,需确保点击时与 Windows 屏幕坐标对齐。
---
## 6. 第一步Umi-OCR API 调用代码参考
你可以让 AI 基于以下片段进行扩展:
```python
import requests
import base64
def call_umi_ocr(image_path):
url = "http://127.0.0.1:1224/api/ocr"
with open(image_path, "rb") as f:
img64 = base64.b64encode(f.read()).decode('utf-8')
payload = {
"base64": img64,
"options": {"data_format": "dict"}
}
response = requests.post(url, json=payload)
return response.json()
```
---