hiroi-sora / Umi-OCR

OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。
MIT License
25.57k stars 2.59k forks source link

http 命令方式调用批量文档接口异常 #588

Closed sunhihi123 closed 2 months ago

sunhihi123 commented 2 months ago

Issues

Umi-OCR version 程序版本

2.1.2.7

Windows version 系统版本

win 10

OCR plugins Used 使用的OCR插件

PaddleOCR

Reproduction steps 复现步骤

按文档描述进行了命令接口请求 报错:Calling "addDocs" in main thread. 我在cmd中执行也是提示这个错误:Calling "addDocs" in main thread. 请问这种情况需要怎么处理

Problem screenshots or related files (optional) 问题截图或相关文件(可选)

测试代码: String url = "http://127.0.0.1:1224/argv"; List list = new ArrayList<>(); list.add("--call_qml"); list.add("BatchDOC_5"); list.add("--func"); list.add("addDocs"); list.add("'[\"E:/db/12/DAT 58-2014 电子档案管理基本术语.pdf\"]'"); String data = JSONUtil.toJsonStr(list); // 发送 POST 请求 HttpResponse response = HttpRequest.post(url) .header("Content-Type", "application/json") .body(data) .execute(); // 检查响应状态码 if (response.getStatus() == 200) { text = response.body().toString(); System.out.println("请求失败,response:" + text); // 打印响应结果 } else { // 处理错误情况 System.out.println("请求失败,response:" + response); }

hiroi-sora commented 2 months ago

你好,其实这个命令和返回值并没有错,让我解释一下。

旧版做法

你的做法是 命令行高级指令 - “将一些PDF文档添加到软件,生成双层可搜索PDF”。这玩意的实质是,用指令代替人工操作,将PDF拖拽到Umi-OCR的“批量文档识别”页面上,然后点击“开始任务”的按钮。随后,你应该可以在软件页面上看到任务已经在跑了。

但是,这种做法只能添加任务,而无法获知任务是否结束,仍需要手动去软件面板上,检查任务进度。

Calling "addDocs" in main thread. 并不是报错,而是告诉你,指令已经被调度到主线程执行了。至于执行是否成功,目前暂时无法获知。

假设传入的PDF文件是 测试.pdf ,那么你也可以让脚本在同目录下不断检查 [OCR]_测试 前缀的文件是否存在。如果存在,那么证明任务结束。

新版做法

更推荐你使用 v2.1.3 版本中,功能更完善的 HTTP PDF 接口。

(注, v2.1.3 尚未发布。目前你可以在github下载main分支的 源码,将源码覆盖粘贴到 v2.1.2 的目录中进行更新。)

新版接口支持通过HTTP上传文件、查询任务进度、生成各种格式的OCR文件、下载生成的文件。

sunhihi123 commented 2 months ago

我安装的最新版V2.1.2.7 开启了允许http 无法打开文档里面:浏览器访问 http://127.0.0.1:1224/api/doc/get_options /api/ 等接口都404

hiroi-sora commented 2 months ago

请问你是使用的 Umi-OCR_Paddle_v2.1.2.7z.exe 或者 Umi-OCR_Rapid_v2.1.2.7z.exe 吗?

这个是最新的稳定版本,还不支持 HTTP PDF 接口功能。你需要手动更新到最新的测试版本

更新步骤:

  1. 点击这里,下载main分支源码
  2. 解压源码,进入 Umi-OCR-main 文件夹,里面有个 UmiOCR-data 文件夹。
  3. 将这个文件夹中的所有内容,复制粘贴到 v2.1.2 稳定版本的 相同文件夹 中,并 覆盖原有文件
sunhihi123 commented 2 months ago

我安装的是Umi-OCR_Paddle_v2.1.2.7z.exe 按上面说的我下载了main分支源码后 解压umiocr-data文件夹到我安装的相同文件夹 现在无法启动exe程序 双击启动 无任何反应

sunhihi123 commented 2 months ago

隔了几分钟 我刚再次双击启动 可以打开了 浏览器访问 http://127.0.0.1:1224/api/doc/get_options 也正常了

hiroi-sora commented 2 months ago

OK,那么如果新接口遇到问题,请继续反馈哈。

如果使用没问题,也可以在这里跟我说一声。

sunhihi123 commented 2 months ago

我用apifox 调用文档上传接口 就能正常返回id 但是我用java调用却不行 测试代码: HttpResponse response = Unirest.post("http://127.0.0.1:1224/api/doc/upload") .header("User-Agent", "Apifox/1.0.0 (https://apifox.com)") .header("Accept", "/") .header("Host", "127.0.0.1:1224") .header("Connection", "keep-alive") .header("Content-Type", "multipart/form-data; boundary=--------------------------631509692675892173111578") .field("file", new File("E:\db\12\测试文件.pdf")) .asString(); //返回: File extension '' is not allowed a1

hiroi-sora commented 2 months ago

稍等,我们会编写一份 java 示例代码,完成后告诉你。

hiroi-sora commented 2 months ago

你好,java的 Unirest 库感觉post多字段表单的时候确实有点奇怪。用标准库组装请求就没有问题。

        String url = "http://127.0.0.1:1224/api/doc/upload";
        String path = "XXXX.pdf";
        String options_json = "{\"doc.extractionMode\": \"fullPage\"}"; // 任务控制参数,json文本
        Path filePath = Paths.get(path);
        // 创建HttpClient实例
        HttpClient client = HttpClient.newHttpClient();
        // 生成boundary
        String boundary = UUID.randomUUID().toString();
        // 构建multipart/form-data请求体
        StringBuilder sb = new StringBuilder();
        // 向表单添加 json 字段
        sb.append("--").append(boundary).append("\r\n");
        sb.append("Content-Disposition: form-data; name=\"json\"\r\n");
        sb.append("Content-Type: application/json\r\n");
        sb.append("\r\n");
        sb.append(options_json).append("\r\n");
        // 向表单添加 file 字段,插入文件
        sb.append("--").append(boundary).append("\r\n");
        sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(filePath.getFileName())
                .append("\"\r\n");
        try {
            sb.append("Content-Type: ").append(Files.probeContentType(filePath)).append("\r\n");
        } catch (IOException e) {
            e.printStackTrace();
            // 如果无法获取文件的 MIME 类型,使用默认值
            sb.append("Content-Type: application/octet-stream\r\n");
        }
        sb.append("\r\n");
        try {
            byte[] fileBytes = Files.readAllBytes(filePath);
            byte[] requestBody = new byte[sb.toString().getBytes().length + fileBytes.length
                    + ("\r\n--" + boundary + "--\r\n").getBytes().length];
            System.arraycopy(sb.toString().getBytes(), 0, requestBody, 0, sb.toString().getBytes().length);
            System.arraycopy(fileBytes, 0, requestBody, sb.toString().getBytes().length, fileBytes.length);
            System.arraycopy(("\r\n--" + boundary + "--\r\n").getBytes(), 0, requestBody,
                    sb.toString().getBytes().length + fileBytes.length,
                    ("\r\n--" + boundary + "--\r\n").getBytes().length);

            // 创建HttpRequest实例
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .header("Content-Type", "multipart/form-data; boundary=" + boundary)
                    .POST(HttpRequest.BodyPublishers.ofByteArray(requestBody))
                    .build();

            // 发送请求并获取响应
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println("Response status code: " + response.statusCode());
            System.out.println("Response body: " + response.body());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }