自动化中经常会碰到“界面上明明看得到文字,但控件和 UIA 都取不到”的情况,例如远程桌面画面、游戏窗口、扫描件、图片报表和自绘界面。这时需要的不是继续发按键,而是先把图片里的文字识别出来。
这套 RapidOCR 封装面向 AutoHotkey v1,底层使用 RapidOcrOnnx、PaddleOCR 模型和 ONNX Runtime 完成本地识别。图片和模型都在本机处理,不依赖在线 OCR 接口,也不需要把截图上传到第三方服务。站内已有的 RapidOcr v2 小模型示例面向 v2,本篇整理的是 v1 调用封装和配套资源。
可以从哪些数据开始识别
- ocr_from_file:直接识别图片文件;
- ocr_from_binary:识别已经读入内存的图片二进制;
- ocr_from_bitmapdata:处理位图数据;
- ocr_from_mat:衔接已有的图像矩阵流程;
- 可只返回拼接后的文本,也可返回文本块、坐标、置信度和角度等完整结果。

识别参数怎么用
OcrParam 可以控制图片边距、最大边长、文本框阈值、展开比例和文字方向检测。新手先使用默认值即可,遇到小字、倾斜文字或背景复杂时,再逐项调整。阈值不是越低越好,过低会把纹理和图标也当成文字。
需要根据坐标点击文字时,应请求完整结果,而不是只取纯文本。识别框坐标可以继续用于画框、排序、筛选区域,或者和 WinCapture、GDI+ 截图流程组合。
运行前必须放齐的文件
目录中要有与 AHK 位数匹配的 RapidOcrOnnx.dll,还要保留检测模型、识别模型、方向分类模型和 ppocr_keys_v1.txt 字典。32 位 AHK 只能加载 32 位 DLL,64 位 AHK 只能加载 64 位 DLL。首次初始化模型会比普通字符串处理慢,建议在脚本启动阶段创建 OCR 对象并重复使用。
下载包里还整理了完整展示报告示例和 OCR Visualization Tool,可把识别文本块、坐标和置信度做成更直观的结果。文章里先放一个不含大型 HTML/JS 的基础 demo,方便新手确认环境是否正常。
本文移植自 thqby 的 ahk2_lib,由本站适配为 AutoHotkey v1 版本,原作者及项目版权归其所有。
源项目地址:https://github.com/thqby/ahk2_lib
打包库和示例的下载地址:
demo代码片段展示:
#Requires AutoHotkey v1.1
#NoEnv
#SingleInstance Force
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%
#Include <RapidOcr_v1>
try
{
ocr := new RapidOcr({models: A_ScriptDir "\models", numThread: 2})
param := new RapidOcr.OcrParam({doAngle: 1, mostAngle: 1})
result := ocr.ocr_from_file(A_ScriptDir "\test.jpg", param, true)
msg := "识别文本:`n" result.text
msg .= "`n`n文本块数量:" result.Length()
MsgBox, 64, RapidOcr v1, %msg%
}
catch e
{
MsgBox, 16, RapidOcr v1, % "识别失败:`n" e.Message
}
ExitApp

评论(2)
大佬,您好,请教下,用原版直接引用库,然后初始化inst := new RapidOCR,就可以用 f := inst.ocr([1554, 376, 400, 100])
但是咱这个不行
; ---- 引擎库(绝对路径,脚本放哪都能跑) ----
#Include D:\AutoHotkey\RapidOCR\RapidOcr_v1.ahk
初始化
ocr := new RapidOcr()
如何用?
; (a) 识别屏幕区域 [x, y, 宽, 高](1554,376 起,宽 400 高 100)
f := inst.ocr([1554, 376, 400, 100])
直接坐标区域的方式读取屏幕上的文字?
RapidOCR库本身没有截图功能【v1和v2都没有】,需要自己构建。网站里也有相关函数
#NoEnv
SetBatchLines -1
#SingleInstance, Force
SetWorkingDir, %A_ScriptDir%
#Include %A_ScriptDir%\RapidOcr_v1.ahk
; 初始化 OCR 引擎
try {
ocr := new RapidOcr({models: A_ScriptDir "\models"})
} catch e {
MsgBox, 16, 错误, % "OCR 初始化失败: " . e.Message
ExitApp
}
; 设置识别参数 (可选)
param := new RapidOcr.OcrParam()
param.doAngle := false ; 不需要判断文字旋转角度可以设为 false 提高速度
; 示例快捷键:按 F2 截取屏幕 (100, 100) 起始、长宽 400x200 区域的文字
F2::
x := 100
y := 100
w := 400
h := 200
text := OcrScreenRegion(ocr, x, y, w, h, param)
MsgBox, % "识别结果:`n" . text
return
; 示例快捷键:按 F3 截取全屏并识别 (如果只需要识别文本)
F3::
text := OcrScreenRegion(ocr, 0, 0, A_ScreenWidth, A_ScreenHeight, param)
MsgBox, % "全屏识别结果:`n" . text
return
/**
* 截取屏幕指定区域并进行 OCR 识别 (针对 AHK v1)
* @param ocr RapidOcr 实例对象
* @param x 屏幕起始 X 坐标
* @param y 屏幕起始 Y 坐标
* @param w 截取宽度
* @param h 截取高度
* @param param RapidOcr.OcrParam 参数对象 (可选)
* @param allresult 是否返回详细识别信息数组,默认 false (仅返回文本)
* @return 识别出的文本字符串 或 OcrResult 对象
*/
OcrScreenRegion(ocr, x, y, w, h, param := 0, allresult := false) {
; 1. 获取屏幕 DC 并创建内存 DC
hScreenDC := DllCall("GetDC", "Ptr", 0, "Ptr")
hMemDC := DllCall("CreateCompatibleDC", "Ptr", hScreenDC, "Ptr")
; 2. 构造 BITMAPINFOHEADER 结构体 (大小 40 字节)
VarSetCapacity(bi, 40, 0)
NumPut(40, bi, 0, "UInt") ; biSize
NumPut(w, bi, 4, "Int") ; biWidth
NumPut(-h, bi, 8, "Int") ; biHeight (负数代表 Top-Down,从上到下的扫描线)
NumPut(1, bi, 12, "UShort") ; biPlanes
NumPut(32, bi, 14, "UShort") ; biBitCount (32位色深: BGRA)
NumPut(0, bi, 16, "UInt") ; biCompression (BI_RGB = 0)
; 3. 创建 32 位 DIBSection 位图并选入内存 DC
ppvBits := 0
hBitmap := DllCall("CreateDIBSection", "Ptr", hMemDC, "Ptr", &bi, "UInt", 0, "Ptr*", ppvBits, "Ptr", 0, "UInt", 0, "Ptr")
hOldBitmap := DllCall("SelectObject", "Ptr", hMemDC, "Ptr", hBitmap, "Ptr")
; 4. 把屏幕指定区域拷贝到内存位图中 (SRCCOPY = 0x00CC0020)
DllCall("BitBlt", "Ptr", hMemDC, "Int", 0, "Int", 0, "Int", w, "Int", h, "Ptr", hScreenDC, "Int", x, "Int", y, "UInt", 0x00CC0020)
; 5. 构造 RapidOcr 所需的 BITMAP_DATA 结构体
; struct BITMAP_DATA { void *bits; uint pitch; int width, height, bytespixel; };
; 32位系统下为 20 字节,64位系统下为 24 字节
bmpDataSize := A_PtrSize + 16
VarSetCapacity(bmpData, bmpDataSize, 0)
pitch := ((w * 32 + 31) & ~31) >> 3 ; 每行步长 (字节对齐)
NumPut(ppvBits, bmpData, 0, "Ptr") ; bits
NumPut(pitch, bmpData, A_PtrSize, "UInt") ; pitch
NumPut(w, bmpData, A_PtrSize + 4, "Int") ; width
NumPut(h, bmpData, A_PtrSize + 8, "Int") ; height
NumPut(4, bmpData, A_PtrSize + 12, "Int") ; bytespixel (32位为4字节)
; 6. 传入 OCR 引擎进行识别
res := ocr.ocr_from_bitmapdata(&bmpData, param, allresult)
; 7. 清理 GDI 句柄资源,防止内存泄露
DllCall("SelectObject", "Ptr", hMemDC, "Ptr", hOldBitmap)
DllCall("DeleteObject", "Ptr", hBitmap)
DllCall("DeleteDC", "Ptr", hMemDC)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hScreenDC)
return res
}