一、背景
工作中要做一个桌面控制相关需求,试了下ClawHub现有Desktop Control skill,发现都有一些不好用的地方,或者与macOS系统不够适配,因此写了一个新skill供大家使用和交流
二、概述
- 这个Skill主要链路如下:
三、具体步骤实现拆解
1.初始化
这一步是最关键的,也是很多现有skill缺失的一步。第一版本先只做Retina屏兼容
在 macOS 上,即使截图和点击都用 Python,也仍然需要先确认几件事情:
1截图图像尺寸是多少 2屏幕逻辑尺寸是多少 3鼠标点击使用的坐标系是什么 4
原因是,在 Retina 屏、缩放显示器、多屏环境下,截图图片的像素尺寸和 pyautogui.size() 返回的逻辑屏幕尺寸可能不同。
比如 Retina 屏上经常会出现这种情况:
1截图图像尺寸:2880 × 1800 2逻辑屏幕尺寸:1440 × 900 3
这意味着截图里的 2 个 pixel,才对应 macOS 逻辑坐标里的 1 个 point。
如果直接拿截图上的像素坐标去点击,就可能点偏。
所以初始化阶段要做的事情是:
用 Python 获取截图尺寸和逻辑屏幕尺寸,计算两者之间的缩放比例,并把结果保存到文件中,供后续流程使用。
2.屏幕截图
截图这一步继续使用 Python 的 pyautogui。
关键点是:截图之后,把图片 resize 到 pyautogui.position() 和 pyautogui.click() 使用的坐标系。
示例代码如下:
1import pyautogui 2 3img = pyautogui.screenshot() 4 5screen_w, screen_h = pyautogui.size() 6 7# 把截图 resize 到 pyautogui.position() / click() 使用的坐标系 8img = img.resize((screen_w, screen_h)) 9 10img.save("screen_logical.png") 11
这一步看似简单,但非常关键。
如果我们后续所有识别都基于 screen_logical.png,那识别结果天然就在逻辑坐标系里,后面的点击会简单很多。
也就是说,我们把坐标统一这件事放到了截图阶段完成:
1截图原始尺寸:2880 × 1800 2逻辑屏幕尺寸:1440 × 900 3resize 后图片:1440 × 900 4OCR / OpenCV 返回坐标:逻辑坐标 5pyautogui.click 使用坐标:逻辑坐标 6
这样整个 skill 的坐标系统会更稳定。
3.图像/文字识别
识别定位可以分成两类:
1文字识别:OCR 2图像识别:OpenCV 3
这两种能力覆盖了大多数桌面自动化场景。
OCR 文字定位
OCR 适合查找界面上的文字,比如按钮文案、菜单项、标题、标签等。
例如:
1查找“确定” 2查找“发送” 3查找“登录” 4查找“保存” 5
流程大致是:
1读取 screen_logical.png 2运行 OCR 3找到匹配文本 4返回文字区域中心点 5
返回结果可以是:
1{ 2 "type": "text", 3 "query": "发送", 4 "x": 1200, 5 "y": 820, 6 "confidence": 0.92 7} 8
然后鼠标点击模块直接点击 (1200, 820)。
OCR 的优点是泛化性强。只要界面上有文字,就不需要提前准备模板图。
但它也有局限,比如小字号、低对比度、特殊字体、中文识别质量等,都可能影响结果。
所以 OCR 更适合这类场景:
1界面文字清晰 2目标按钮有明确文案 3需要查找的内容不固定 4不想提前维护模板图片 5
OpenCV 图像定位
OpenCV 更适合查找图标、按钮、头像、固定 UI 区块等视觉目标。
例如:
1查找某个 App 图标 2查找关闭按钮 3查找发送图标 4查找某个固定图片区域 5
典型做法是模板匹配:
1读取 screen_logical.png 2读取 template.png 3使用 OpenCV matchTemplate 4找到最高匹配区域 5返回中心点 6
返回结果可以是:
1{ 2 "type": "image", 3 "template": "send_button.png", 4 "x": 1185, 5 "y": 835, 6 "confidence": 0.88 7} 8
OpenCV 的优点是对图形元素定位更稳定,不依赖文字识别。
但它也有局限。界面缩放、主题变化、深色模式、按钮状态变化,都可能影响匹配结果。
所以这两种方式最好同时保留:
1有文字 → 优先 OCR 2有图标 → 使用 OpenCV 3复杂场景 → OCR + OpenCV 组合验证 4
4.鼠标点击
最后一步是鼠标点击。
这里仍然用 Python 实现,继续使用 pyautogui:
1import pyautogui 2 3pyautogui.click(x, y) 4
为了让它更适合作为 skill 使用,点击脚本最好支持命令行参数:
1python scripts/mouse/click.py --x 1200 --y 820 2
也可以增加一些常用选项:
1python scripts/mouse/click.py --x 1200 --y 820 --duration 0.1 2python scripts/mouse/click.py --x 1200 --y 820 --button left 3python scripts/mouse/click.py --x 1200 --y 820 --double 4
这样 OpenClaw 在拿到定位结果后,就可以直接调用点击脚本完成操作。
因为前面的截图和识别都已经统一到了逻辑坐标,所以点击阶段不需要再做复杂转换:
1识别结果 x, y → pyautogui.click(x, y) 2
这也是为什么前面的坐标统一非常重要。
四、GitHub & ClawHub
- GitHub:github.com/KD-oauth/ma…
- ClawHub:clawhub.ai/kd-oauth/de…


