From fd66a641f61b765740852a085d12d8bab2d62398 Mon Sep 17 00:00:00 2001 From: Gy Hu Date: Thu, 29 Dec 2022 14:58:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Eocr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++--- src/api.cc | 10 +++++++ src/api.h | 1 + src/ocr.cc | 61 ++++++++++++++++++++++++++++++++++++++++ src/ocr.h | 5 ++++ 5 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 src/ocr.cc create mode 100644 src/ocr.h diff --git a/README.md b/README.md index bd3a2a9..93e326c 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,48 @@ Visual Studio code cmake vcpkg +#### 构建步骤 +以下是在vscode中操作,vs中的操作类似。 +1.安装vcpkg,cmake,vscode +2.安装相应的库,如果安装的版本不同,则根据vcpkg安装成功后提示的find_package修改CMakeLists.txt内容即可。或者自己编译。 +``` + vcpkg install mongoose + vcpkg install nlohmann-json +``` +3.vscode 配置CMakePresets.json,主要设置CMAKE_C_COMPILER 和CMAKE_CXX_COMPILER 为cl.exe.参考如下 +``` + { + "name": "x86-release", + "displayName": "x86-release", + "description": "Sets Ninja generator, build and install directory", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "architecture":{ + "value": "x86", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe", + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_TOOLCHAIN_FILE": { + "value": "C:/soft/vcpkg/scripts/buildsystems/vcpkg.cmake", + "type": "FILEPATH" + } + }, + "environment": { + + } + + } +``` +4.vscode中右键configure all projects,在Terminal中点击Run Task,如没有先配置build任务,然后运行即可 #### 更新说明 2022-12-26 : 增加3.8.1.26版本支持。 - +2022-12-29 : 新增提取文字功能。 ### 接口文档: @@ -60,7 +97,6 @@ vcpkg |data|string|响应内容| ###### 接口示例 -地址:https://www.bincoding.cn/test 入参: ``` javascript ``` @@ -107,7 +143,6 @@ vcpkg |wxid|string|wxid| ###### 接口示例 -地址:https://www.bincoding.cn/test 入参: ``` javascript ``` @@ -143,7 +178,7 @@ vcpkg ###### 接口示例 -地址:https://www.bincoding.cn/test + 入参: ``` javascript { @@ -691,6 +726,44 @@ vcpkg ``` + +#### 49.提取文字** +###### 接口功能 +> 提取图片中的文字 + +###### 接口地址 +> [/api/?type=49](/api/?type=49) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|imagePath |ture |string| 图片路径 | + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,0成功, -1失败,1 2 则是缓存或者正在进行中需再调用一次| +|result|string|成功提示| +|text|string|提取的相应文字| + + +###### 接口示例 +入参: +``` javascript +{ + "imagePath":"C:\\3a610d7bc1cf5a15d12225a64b8962.dat" +} + +``` +响应: +``` javascript +{"code":0,"result":"OK","text":"搜索商品新闻简报小程序上线啦!!!我的收藏地址管理促销单品多买多省热门榜单热门榜单首发新品精品推荐精品推荐首发新品FRONTI警微安奈儿 童装冬季款男¥39900¥59.90帕拉丁品牌 时尚双背包409 00¥49.90我是有底线的首页分类购物车我的"} +``` + + #### 感谢 https://github.com/ljc545w/ComWeChatRobot diff --git a/src/api.cc b/src/api.cc index 10f5d5b..82b0b51 100644 --- a/src/api.cc +++ b/src/api.cc @@ -18,6 +18,7 @@ #include "chat_room.h" #include "self_info.h" #include "hook_img.h" +#include "ocr.h" #pragma comment(lib, "ws2_32.lib") using namespace std; @@ -535,6 +536,15 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) { int success = GetImgByName(WS2LW(image_path),WS2LW(save_path)); json ret_data = {{"code", success}, {"result", "OK"}}; ret = ret_data.dump(); + break; + } + case WECHAT_DO_OCR:{ + wstring image_path = get_http_req_param(hm, j_param, "imagePath", is_post); + string text(""); + int success = DoOCRTask(WS2LW(image_path),text); + json ret_data = {{"code", success}, {"result", "OK"},{"text",text}}; + ret = ret_data.dump(); + break; } default: break; diff --git a/src/api.h b/src/api.h index 4ecd6e3..e1fe71b 100644 --- a/src/api.h +++ b/src/api.h @@ -63,6 +63,7 @@ typedef enum WECHAT_HTTP_APISTag WECHAT_GET_CONTACT_ALL, WECHAT_GET_CHATROOM_INFO, WECHAT_GET_IMG_BY_NAME, + WECHAT_DO_OCR, } WECHAT_HTTP_APIS, *PWECHAT_HTTP_APIS; diff --git a/src/ocr.cc b/src/ocr.cc new file mode 100644 index 0000000..28d6b42 --- /dev/null +++ b/src/ocr.cc @@ -0,0 +1,61 @@ +#include "pch.h" +#include "ocr.h" + +#include "common.h" +#include "wechat_data.h" + +#define WX_INIT_OBJ_OFFSET 0x6cbab0 +#define WX_OCR_MANAGER_OFFSET 0x6cff00 +#define WX_DO_OCR_TASK_OFFSET 0x11e3210 + +int DoOCRTask(wchar_t *img_path, std::string &result) { + int success = -1; + WeChatString path(img_path); + WeChatString null_obj = {0}; + WeChatString ocr_result = {0}; + DWORD base = GetWeChatWinBase(); + DWORD ocr_manager_addr = base + WX_OCR_MANAGER_OFFSET; + DWORD do_ocr_task_addr = base + WX_DO_OCR_TASK_OFFSET; + DWORD init_addr = base + WX_INIT_OBJ_OFFSET; + __asm { + PUSHAD + PUSHFD + LEA ECX,ocr_result + CALL init_addr + CALL ocr_manager_addr + LEA ECX,null_obj + PUSH ECX + LEA ECX,ocr_result + PUSH ECX + PUSH ECX + LEA ECX,path + PUSH ECX + MOV ECX,EAX + CALL do_ocr_task_addr + MOV success,EAX + POPFD + POPAD + } + + if (success == 0) { + DWORD addr = (DWORD)&ocr_result; + DWORD ptr = *(DWORD *)addr; + DWORD num = *(DWORD *)(addr + 0x4); + if (num <= 0) { + return success; + } + + DWORD header = *(DWORD *)ptr; + for (unsigned int i = 0; i < num -1; i++) { + DWORD content = *(DWORD *)header; + result += unicode_to_utf8((wchar_t *)READ_WSTRING(content, 0x14).c_str()); + + header = content; + } +#ifdef _DEBUG + cout << "num:" << num << endl; + cout << "all:" << result << endl; +#endif + } + return success; +} \ No newline at end of file diff --git a/src/ocr.h b/src/ocr.h new file mode 100644 index 0000000..b6e73aa --- /dev/null +++ b/src/ocr.h @@ -0,0 +1,5 @@ +#ifndef OCR_H_ +#define OCR_H_ +#include +int DoOCRTask(wchar_t* img_path,std::string &result); +#endif \ No newline at end of file