回答
在 Hamibot 中,你可以通过截图匹配目标图案来获取其在屏幕上的位置,核心是使用 findImage 函数在大图(当前屏幕截图)中查找小图(目标图案)的位置。
以下是操作步骤与示例代码:
// 文档地址 https://docs.hamibot.com/
// 1. 请求截图权限
if (!requestScreenCapture()) {
toastLog('没有授予 Hamibot 屏幕截图权限');
hamibot.exit();
}
// 2. 等待截图权限生效并截取当前屏幕
sleep(1000);
var screen = captureScreen();
// 3. 读取目标图案的图片文件(建议放在 /storage/emulated/0/ 目录下)
var target = images.read('/storage/emulated/0/目标图案.png');
if (!target) {
toastLog('目标图案图片加载失败');
hamibot.exit();
}
// 4. 在截图中查找目标图案,返回第一个匹配点
var point = findImage(screen, target);
if (point) {
toastLog('找到目标图案,位置:(' + point.x + ', ' + point.y + ')');
} else {
toastLog('未找到目标图案');
}
// 5. 释放图片资源(可选但推荐)
target.recycle();
screen.recycle();
如果需要限定搜索区域,可以传入区域参数,例如在屏幕左上角 (100, 200) 宽 300 高 400 区域内查找:
var point = findImage(screen, target, {
region: [100, 200, 300, 400]
});
如果目标图案颜色单一,也可使用 findColor 直接定位颜色点,但图案匹配通常用 findImage 更健壮。
目标图案不需要与截图中的图案完全一致,但需要足够相似,以便 findImage 能够匹配到。
findImage 默认使用相似度阈值来判断匹配,你可以在选项中通过 threshold 参数调整匹配的严格程度:
- 默认阈值:通常为 0.9,表示相似度需要达到 90% 才会被匹配。
- 降低阈值:如果图案存在轻微变形、颜色差异或缩放,可以降低阈值(如 0.8)来放宽匹配条件。
- 提高阈值:如果误匹配其他图案,可以提高阈值(如 0.95)来要求更精确的匹配。
示例:
var point = findImage(screen, target, {
threshold: 0.8 // 相似度达到 80% 即视为匹配
});
提高匹配准确度的建议:
- 让目标图案截图尽量与运行时屏幕上出现的图案在分辨率、颜色、风格上保持一致(例如同一个设备、同一主题下截取)。
- 避免在目标图案中包含易变化的背景元素(如动态文字、进度条),尽量截取特征明显的固定部分。
- 如果图案颜色单一,可以尝试
findColor配合颜色容差,但图案匹配通常更稳健。
如果匹配失败,可以尝试降低阈值或检查目标图案是否被正确截取。
提高 findImage 找图准确率,可以从以下几个方面入手:
1. 优化目标图案本身
- 截取特征明显的部分,避开纯色背景、动态文字或进度条等易变元素。
- 确保目标图案与运行时屏幕上的图案分辨率、颜色、风格一致,最好在同一设备上截取。
2. 调整相似度阈值
通过 threshold 参数灵活控制匹配严格程度。如果误匹配其他图案,可提高阈值;如果匹配不到,可适当降低。
var point = findImage(screen, target, {
threshold: 0.95 // 提高相似度要求,减少误匹配
});
3. 限定搜索区域
使用 region 参数将搜索范围缩小到目标图案可能出现的区域,既能提高准确率,也能提升速度。
var point = findImage(screen, target, {
region: [150, 300, 500, 200] // [x, y, width, height]
});
4. 获取多个匹配结果并筛选
使用 findImage 返回 MatchingResult 对象的场景,可以获取多个匹配结果,然后按相似度排序,取相似度最高的那个。
var result = findImage(screen, target, {
threshold: 0.8,
max: 10 // 最多返回10个结果
});
if (result && result.matches.length > 0) {
// 按相似度降序排序,取最匹配的
result.matches.sort(function(a, b) {
return b.similarity - a.similarity;
});
var best = result.matches[0];
toastLog('最佳匹配位置:(' + best.point.x + ', ' + best.point.y + ') 相似度:' + best.similarity);
}
5. 避免使用 level 参数
level 参数一般不必修改。调整不当可能导致图片因过度缩小而无法分辨,反而降低准确率。
6. 多图案兜底
如果目标图案在不同场景下可能有细微变化(如按钮的不同状态),可以准备多张目标图,逐个尝试匹配,提高命中率。