文字识别后,如何获取坐标,并点击这个按钮

已存档
HAMI_8366156507 · 26 天前
第 1 条补充
·
26 天前

获取到文字位置坐标后转换坐标,如何做

第 2 条补充
·
26 天前

这段代码,为什么点击不了

function ocr_find(txt) {
let res = ocr.recognize(captureScreen());
let index_right = null;
for (var index in res['results']) {
if (res['results'][index]['text'].indexOf(txt) != -1) {
index_right = index;
break;
}
}
if (index_right) {
log(
'"' +
txt +
'"' +
'匹配到文字块:"' +
res['results'][index_right]['text'] +
'"'
);
log(
'该文字块左上角坐标:' +
res['results'][index_right]['bounds']['left'] +
',' +
res['results'][index_right]['bounds']['top']
);
log(
'该文字块右下角坐标:' +
res['results'][index_right]['bounds']['right'] +
',' +
res['results'][index_right]['bounds']['bottom']
);
click(res['results'][index_right]['bounds']['left'],res['results'][index_right]['bounds']['top'],res['results'][index_right]['bounds']['bottom'],res['results'][index_right]['bounds']['right'])
log('原始数据:\n' + JSON.stringify(res['results'][index_right]));
} else log('OCR未找到' + '"' + txt + '"');
}

回答

Hamibot AI
1
· 26 天前

在 Hamibot 中获取文字识别后的坐标并点击按钮,主要有以下几种方法:

方法一:基于控件识别(推荐)

如果按钮是控件(如 TextView、Button),可以直接通过文本查找并点击:

// 文档地址 https://docs.hamibot.com/
var btn = text("按钮文字").findOne();
btn.click();

方法二:获取控件坐标后点击

如果控件无法直接点击(clickable 为 false),可以获取其中心坐标进行点击:

// 文档地址 https://docs.hamibot.com/
var widget = text("按钮文字").findOne();
var bounds = widget.bounds();
var x = bounds.centerX();
var y = bounds.centerY();

// Android 7.0+ 可用
click(x, y);

// 或有 root 权限时使用
// Tap(x, y);

方法三:纯坐标点击(需注意屏幕适配)

如果需要使用 OCR 文字识别获取坐标,建议:

  1. 先通过 setScreenMetrics() 设置设计分辨率
  2. 获取到文字位置坐标后转换坐标
  3. 执行点击操作
// 文档地址 https://docs.hamibot.com/
// 设置设计分辨率(以 1080x1920 为例)
setScreenMetrics(1080, 1920);

// 假设通过 OCR 获取到文字中心坐标为 (500, 800)
var targetX = 500;
var targetY = 800;

// 执行点击
click(targetX, targetY);
sleep(500); // 建议添加适当延迟

注意事项:

  1. 优先使用控件识别方式,比坐标点击更稳定
  2. 不同分辨率设备需使用 setScreenMetrics() 进行坐标适配
  3. 点击后建议添加 sleep() 等待操作完成
  4. Android 7.0 以下或需要 root 权限时使用 Tap() 函数

如果需要更详细的帮助,可以提供具体的按钮特征和场景信息。


补充回答 1

在Hamibot中,获取文字位置坐标通常通过OCR功能(如ocr.recognizeText())实现,返回的坐标是相对于屏幕左上角的绝对坐标。如果你需要将这些坐标转换为其他坐标系(例如相对于某个控件或窗口),可以通过简单的数学计算来实现。以下是具体步骤和示例:

步骤1: 获取文字位置坐标

使用OCR识别文本,并提取坐标。例如:

// 文档地址 https://docs.hamibot.com/
// 识别屏幕上的文本
let result = ocr.recognizeText(captureScreen(), {
    region: [0, 0, device.width, device.height]
});
// 假设result包含文本及其边界框,例如bounds对象
if (result) {
    let textX = result.bounds.left; // 文本左上角的X坐标
    let textY = result.bounds.top;  // 文本左上角的Y坐标
    // 其他坐标信息如right、bottom也可用
}

步骤2: 转换坐标

根据你的需求,进行坐标转换。常见场景包括:

  • 转换为相对坐标:如果你有一个控件或区域的左上角屏幕坐标(ctrlX, ctrlY),可以将文本坐标转换为相对于该控件的坐标。
  • 缩放坐标:如果屏幕分辨率或缩放比例变化,可以应用缩放因子。

示例代码:

// 文档地址 https://docs.hamibot.com/
// 假设控件的屏幕坐标
let ctrlX = 100; // 控件左上角X
let ctrlY = 100; // 控件左上角Y

// 转换文本坐标为相对坐标
let relativeX = textX - ctrlX;
let relativeY = textY - ctrlY;

// 如果需要缩放坐标(例如缩放因子为2)
let scaleFactor = 2;
let scaledX = textX * scaleFactor;
let scaledY = textY * scaleFactor;

// 输出转换后的坐标
console.log("相对坐标:", relativeX, relativeY);
console.log("缩放坐标:", scaledX, scaledY);

注意事项

  • 坐标转换基于简单的加减或乘除运算,确保参考点(如控件位置)的坐标准确。
  • 如果你在处理图像或画布,可以使用canvas模块的变换函数(如translatescale),但这通常用于绘图上下文,而不是直接用于OCR坐标转换。
  • 在UI自动化中,坐标通常是屏幕绝对坐标,转换前请确认目标坐标系的原点。

如果你有更具体的转换需求(如旋转或复杂变换),请提供更多细节,我可以进一步协助。


补充回答 2

你的代码中点击不了的原因可能涉及几个方面,包括缺少屏幕截图权限、OCR识别结果的处理问题,以及点击函数的用法不当。下面我将逐一分析并提供改进建议。

主要原因分析:

  1. 缺少屏幕截图权限:你的代码中使用 captureScreen() 进行截图,但在此之前没有请求屏幕截图权限。Hamibot 需要显式请求权限才能捕获屏幕内容。如果没有权限,captureScreen() 可能返回空或无效图像,导致 OCR 识别失败。
  2. OCR识别结果的结构可能不匹配ocr.recognize() 返回的对象结构可能与你代码中假设的 res['results'] 不一致。Hamibot 的 OCR 模块返回的数据结构可能因版本而异,直接访问 results 属性可能不正确。
  3. 点击函数使用不当:你使用了 click(left, top, bottom, right) 这个四参数版本,但根据 Hamibot 文档,这个函数通常只用于录制的脚本,在实际代码中可能不可靠。建议使用坐标点击(双参数版本)或计算中心点点击。
  4. 索引处理问题:你的代码中 index_right 初始为 null,但循环中如果找到匹配,index_right 被设置为索引(字符串类型)。条件 if (index_right) 可能在某些情况下失败(例如索引为 0 时),因为 0 在 JavaScript 中被视为 falsy。

改进后的代码:

以下是修改后的代码,添加了权限请求、调整了 OCR 结果处理,并改用中心点点击。同时,我添加了注释以解释关键步骤。

// 文档地址 https://docs.hamibot.com/
// 请求屏幕截图权限和自动化服务
auto.waitFor();
if (!requestScreenCapture()) {
    toastLog('没有授予 Hamibot 屏幕截图权限');
    hamibot.exit();
}

function ocr_find(txt) {
    // 捕获屏幕图像
    let img = captureScreen();
    if (!img) {
        log('截图失败,请检查权限');
        return;
    }
    
    // 识别文本
    let res = ocr.recognize(img);
    // 检查识别结果的结构:res 可能是一个对象或数组,具体取决于版本
    // 常见结构是 res.results 或直接是数组,建议先打印 res 以确认
    // log(JSON.stringify(res)); // 调试时取消注释以查看结构
    
    let foundResult = null;
    // 处理识别结果:假设 res 有 results 属性(数组)
    if (res && res.results && Array.isArray(res.results)) {
        for (let i = 0; i < res.results.length; i++) {
            let result = res.results[i];
            if (result.text && result.text.indexOf(txt) !== -1) {
                foundResult = result;
                break;
            }
        }
    } else {
        log('OCR识别结果格式异常,请检查OCR模块版本');
        return;
    }
    
    if (foundResult) {
        let bounds = foundResult.bounds;
        log('匹配到文字块:"' + foundResult.text + '"');
        log('该文字块左上角坐标:' + bounds.left + ',' + bounds.top);
        log('该文字块右下角坐标:' + bounds.right + ',' + bounds.bottom);
        
        // 计算文本块的中心点坐标
        let centerX = Math.floor((bounds.left + bounds.right) / 2);
        let centerY = Math.floor((bounds.top + bounds.bottom) / 2);
        
        // 点击中心点(使用双参数 click)
        click(centerX, centerY);
        log('点击坐标: ' + centerX + ', ' + centerY);
    } else {
        log('OCR未找到"' + txt + '"');
    }
}

使用示例:

调用 ocr_find("需要点击的文本") 即可。例如:

ocr_find("确定");

注意事项:

  • 权限请求:确保在脚本开头请求 auto.waitFor()requestScreenCapture(),否则截图可能失败。
  • OCR结果结构:Hamibot 的 ocr.recognize() 返回的结构可能随时间变化。如果上述代码仍不工作,建议先打印 res 对象(使用 log(JSON.stringify(res)))来查看实际结构,并调整代码 accordingly。
  • 点击延迟:有时点击需要等待界面稳定。在点击前添加 sleep(500) 可能有助于提高可靠性。
  • 屏幕旋转:如果屏幕旋转,坐标系统可能变化,确保在正确的屏幕方向下手动处理坐标。

如果问题依旧,请提供更多上下文(如Hamibot版本、OCR识别结果日志),以便进一步排查。

ℹ️ 本回答由 AI 生成,内容仅供参考