-
Notifications
You must be signed in to change notification settings - Fork 251
python dm ocr
qiannian edited this page Jun 13, 2026
·
1 revision
本示例基于项目中的 examples/bind.py,演示使用 Python SWIG 模块 pyop 绑定 MuMu 模拟器窗口,并加载大漠文本点阵字库进行 OcrEx 和 FindStr 识别。
示例假设脚本目录下已经放好这些文件:
demo.py
pyop.py
_pyop.pyd
op_x64.dll
dm_soft.txt
其中 dm_soft.txt 是大漠文本点阵字库,格式为:
点阵HEX$文本$左.右.数量$高度
例如:
FFFFFFFFFF$字$0.0.10$11
from pathlib import Path
import pyop
def find_mumu_handles(op):
# 查找 MuMu 主窗口
parent_hwnd = op.FindWindow("", "MuMu安卓设备")
if parent_hwnd == 0:
raise RuntimeError("没有找到 MuMu安卓设备 窗口")
# 枚举 MuMu 子窗口,分别找显示窗口和输入窗口
display_hwnd = 0
input_hwnd = 0
hwnds = op.EnumWindow(parent_hwnd, "", "", 0)
for hwnd_text in hwnds.split(","):
if not hwnd_text:
continue
hwnd = int(hwnd_text)
title = op.GetWindowTitle(hwnd)
print("child hwnd:", hwnd, "title:", title)
# nemudisplay 用于截图显示
if title == "nemudisplay":
display_hwnd = hwnd
# MuMuNxDevice 用于后台鼠标键盘输入
if title == "MuMuNxDevice":
input_hwnd = hwnd
if display_hwnd == 0 or input_hwnd == 0:
raise RuntimeError("没有找到 MuMu 的显示窗口或输入窗口")
return display_hwnd, input_hwnd
def bind_mumu(op, display_hwnd, input_hwnd):
# 双句柄绑定:显示和输入分开传入
ret = op.BindWindowEx(display_hwnd, input_hwnd, "dx2", "dx", "dx", 0)
if ret != 1:
raise RuntimeError("绑定 MuMu 窗口失败")
def load_dm_dict(op, dict_path):
# 加载大漠文本点阵字库
ret = op.SetDict(0, str(dict_path))
if ret != 1:
raise RuntimeError(f"加载字库失败: {dict_path}")
# 使用第 0 号字库
op.UseDict(0)
def recognize_and_click(op, width, height):
# 大漠找字常用颜色格式:颜色-偏色,多组颜色用 | 分隔
color = "ffffff-303030|c7c9ca-303030"
sim = 0.9
# 返回区域内识别到的文字和坐标信息
ocr_result = op.OcrEx(0, 0, width, height, color, sim)
print("OcrEx:", ocr_result)
# 查找指定文字;pyop 返回 x, y, ret
x, y, ret = op.FindStr(0, 0, width, height, "诛仙", color, sim)
print("FindStr:", {"ret": ret, "x": x, "y": y})
if ret == 1:
# 找到文字后移动并点击
op.MoveTo(x, y)
op.LeftClick()
def main():
root = Path(__file__).resolve().parent
dict_path = root / "dm_soft.txt"
op = pyop.libop()
print("op version:", op.Ver())
display_hwnd, input_hwnd = find_mumu_handles(op)
try:
bind_mumu(op, display_hwnd, input_hwnd)
# 获取绑定显示窗口的客户区大小
width, height = op.GetClientSize(display_hwnd)
print("client size:", width, height)
# 截图用于确认绑定是否正常
if op.Capture(0, 0, width, height, "mumu.png") != 1:
raise RuntimeError("截图失败")
load_dm_dict(op, dict_path)
recognize_and_click(op, width, height)
finally:
# 使用完成后解除绑定
op.UnBindWindow()
if __name__ == "__main__":
main()- 这个示例使用的是
pyop.libop(),需要pyop.py、_pyop.pyd和对应位数的op_x64.dll/op_x86.dll。 -
BindWindowEx(display_hwnd, input_hwnd, ...)适合 MuMu 这类显示窗口和输入窗口分离的场景。 -
SetDict可以直接加载大漠文本点阵字库;字库加载成功后,OcrEx/FindStr/FindStrEx会走本地点阵字库识别。 -
FindStr在pyop中返回顺序为x, y, ret,ret == 1表示找到目标文字。 - 如果窗口标题和当前 MuMu 版本不一致,请先打印子窗口标题,再调整
nemudisplay和MuMuNxDevice的匹配条件。