屏幕上的图片和文字
在没有元素的游戏和自绘界面上,从截图中找到图片并点击,或者用 OCR 读取文字。两者都是可选功能,在电脑上运行。
本页为译文。如与英文版不一致,以英文版为准。 English
游戏、地图和一些自行绘制界面的应用不提供元素,dump 中只有一个大方框。坐标在这里能用,但布局一变就会失效。下面两组可选命令改为查看截图:
find_image和tap_image查找你从之前的截图中裁剪下来的小图片。ocr、ocr_find和ocr_tap用 Tesseract 读取屏幕上的文字。
两者都在运行 droidline serve 的电脑上执行:服务器从手机获取截图并在本地处理,手机上不需要任何新东西。只要 dump 中有元素,就使用元素;它们更快,也更准确。
找到图片并点击
- 截一张原始尺寸的图:
droidline screenshot screen.png。 - 用任意图片编辑器打开,把想要的按钮或图标裁剪下来,比它的边缘稍微往里一点。保存为 PNG。
- 查找它:
spot = d.find_image("play-button.png")
print(spot["x"], spot["y"], spot["score"]) # 中心坐标,以及匹配有多接近
d.tap_image("play-button.png") # 找到后点击它的中心
d.tap_image("next.png", threshold=0.8, timeout=20)const spot = await d.findImage("play-button.png");
console.log(spot.x, spot.y, spot.score);
await d.tapImage("play-button.png");
await d.tapImage("next.png", { threshold: 0.8, timeout: 20 });var spot = await d.FindImageAsync("play-button.png");
Console.WriteLine($"{spot.X} {spot.Y} {spot.Score}");
await d.TapImageAsync("play-button.png");
await d.TapImageAsync("next.png", threshold: 0.8, timeout: 20);droidline find_image play-button.png
droidline tap_image play-button.png
droidline tap_image next.png --threshold 0.8 --timeout 20SDK 也可以传入图片的字节,而不是路径。
两个命令都会不断重试,直到图片出现或 timeout(默认 10 秒)用完,然后以 NOT_FOUND 失败。错误信息会给出它见到的最高分,让你知道差了多少。
怎样才能匹配上:
- 从同一部手机上裁剪。 图片按相同尺寸逐像素比较,所以来自其他屏幕尺寸或密度的图片匹配不上。每种手机型号各保留一套图片。
- 裁剪有辨识度的部分。 纯色方块会在很多地方匹配上,而上面的文字或图标只会匹配一处。
- 谨慎调整
threshold。 它的范围是 0 到 1,默认 0.9。按钮会有细微变化时(例如发光效果或数字),可以稍微调低。调得太低会点到别的东西。
用 OCR 读取文字
OCR 需要在运行服务器的电脑上安装 Tesseract,以及要读取的语言数据:英语是 eng,韩语是 kor,简体中文是 chi_sim。Droidline 不会替你安装。如果 tesseract 不在 PATH 中,在 config.toml 中写明它的位置:
[ocr]
tesseract = "C:/Program Files/Tesseract-OCR/tesseract.exe"
然后:
page = d.ocr("chi_sim+eng")
print(page["text"]) # 所有行,每行一条
for line in page["lines"]:
print(line["text"], line["bounds"])
d.ocr_find("第 12 关", "chi_sim") # 等它出现,返回位置
d.ocr_tap("开始", "chi_sim", timeout=30) # 等它出现,然后点击const page = await d.ocr("chi_sim+eng");
console.log(page.text);
for (const line of page.lines) console.log(line.text, line.bounds);
await d.ocrFind("第 12 关", "chi_sim");
await d.ocrTap("开始", "chi_sim", { timeout: 30 });var page = await d.OcrAsync("chi_sim+eng");
Console.WriteLine(page.Text);
foreach (var line in page.Lines)
Console.WriteLine($"{line.Get<string>("text")} [{string.Join(", ", line.Get<int[]>("bounds")!)}]");
await d.OcrFindAsync("第 12 关", "chi_sim");
await d.OcrTapAsync("开始", "chi_sim", timeout: 30);droidline ocr chi_sim+eng
droidline ocr_find "第 12 关" chi_sim
droidline ocr_tap 开始 chi_sim --timeout 30ocr_find 和 ocr_tap 先查找与你的文字完全相同的单词,再查找包含它的行。没有 Tesseract 时,它们以 OCR_UNAVAILABLE 失败,并说明缺少什么。
OCR 读取的是图片上显示的内容,所以比元素慢,遇到很小、有装饰或对比度低的文字时也会出错。每次尝试都要截图并运行一次 Tesseract,比查找元素慢得多。