# autojs-easyedge-nodejs **Repository Path**: yashujs/autojs-easyedge-nodejs ## Basic Information - **Project Name**: autojs-easyedge-nodejs - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 8 - **Forks**: 1 - **Created**: 2021-12-03 - **Last Updated**: 2024-05-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # autojs-ocr-easyedge-nodejs 牙叔教程 简单易懂 ## 目的 做一个有ocr功能的app ## easyedge 是百度的产品, 有ocr功能, 且其发布了一个免费的离线app, 识别率还可以 ## autojs引擎 从autojspro9开始, 就有了两个引擎 ![01引擎](./img/01引擎.png) autojs内置nodejs, rhino, 并且支持双方通信 ## 实现ocr的思路 如果会安卓开发的话, 可以把百度开源的paddle做成插件, 提供给autojs使用; 我不会安卓开发, 所以我选择了nodejs, 把ocr功能单独做一个app, 提供给脚本使用. 那么我们要实现这么一个接口. http发送ocr请求, 然后返回ocr识别后的内容, 这里就出现了一个**CS架构** ![02CS架构](./img/02CS架构.png) 客户端 就一个http请求 ``` let imgPath = "/sdcard/02.png"; var url = "http://127.0.0.1:34567/"; let r = http.postJson(url, { action: "ocr", imgPath: imgPath, }); let obj = r.body.json(); log(obj.result); ``` 服务端 这个服务端的app大概要做哪些事情? 首先, 要接收客户端的请求, 必然要开启服务, 服务我们用的是koa, 大致流程如下 ![03大概流程图](./img/03大概流程图.png) 这里就涉及到 了java和nodejs的通信问题: easyedge是用的java, koa是nodejs. ## java和nodejs通信 ##### 1. java给nodejs发消息: 这里首先要获取启动nodejs脚本的引擎, 然后再发送消息 ``` const execution = $engines.execScriptFile("./server/index.js", { arguments: { serverEngineId: $engines.myEngine().id, }, }); sleep(1000); execution.engine.emit("ocrResult", { action: "ocr", result: ocrResult, }); ``` ##### 2. nodejs给java发消息 同上, 这里也要获取java的引擎, 然后再发送消息 ``` // 从参数中取出Rhino引擎的ID const serverEngineId = engines.myEngine().execArgv.serverEngineId; // 根据ID找出Rhino引擎 const serverEngine = engines.getRunningEngines().find((e) => e.id === serverEngineId); serverEngine.emit("reply", params); ``` ##### 3. java接收消息 ``` $events.on("reply", (data) => {}); ``` ##### 4. nodejs接收消息 ``` engines.myEngine().on("ocrResult", (ocrResult) => {}); ``` ## nodejs怎么知道ocr识别完成 ocr识别图片里的文字是需要消耗时间的, 那么nodejs怎么知道ocr识别何时完成? http--> nodejs--> easyedge--> nodejs; nodejs仅仅只能把http发送的数据, 使用serverEngine.emit发送给java, 他的ctx是发送不过去的, 到这一步, nodejs就控制不了easyedge了, nodejs能做的仅仅是和java交换一些简单的数据, ctx是交换不了的. 既然ocr需要时间, 那么我们先让http等一些时间, 再发送响应 ``` new Promise(function (resolve, reject) { let setTimeoutId = setTimeout(function () { resolve(currentOcrResult); }, 8000); }); ``` 这里使用的是promise, 延迟了8秒. easyedge我测试了一下, 一般的图片1秒以内就返回数据了, 图片太大, 文字太多, 时间会更长一些, 不过8秒应该够了. 我们需要等8秒吗? 在8秒内, 我们可以每隔一段时间检查一下java是否把ocr识别的结果传给了nodejs, 如果nodejs接收到ocr的数据, 我们就可以中断这8秒钟的等待了 ``` let setIntervalId = setInterval(function () { if (currentOcrResult) { clearTimeout(setTimeoutId); resolve(currentOcrResult); clearInterval(setIntervalId); } }, 30); ``` 我觉得这个setTimeout和setInterval配合Promise等待ocr识别结果, 这个思路是本教程的精华. ## easyedge怎么封装到app里面 可以查看我之前的合并教程 [autojs合并EasyEdge](https://www.yuque.com/yashujs/bfug6u/wc7ng2) autojs9.0.10之前应该都可以依照此方法合并, 在autojs9.0.11合并的时候, 不可以添加新的classes.dex到app中了, 会报错, 堆栈异常之类的.; 我们需要把classes.dex放到我们的脚本项目中, 然后用loaddex加载dex. ## 环境 手机: Mi 11 Pro Android版本: 11 Autojs版本: 9.0.11 ## 名人名言 思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程 ## 声明 部分内容来自网络 本教程仅用于学习, 禁止用于其他用途 ​ ## bilibili [牙叔教程](https://space.bilibili.com/26079586) ​ ## 微信公众号 牙叔教程 ![](牙叔教程公众号.jpg)​ ​ ## QQ群 747748653 ![](牙叔教程q群.png)