为什么我无法捕获 TesseractException?

Why can't I catch the TesseractException?

我正在使用 Tess4j 来使用 Tesseract-OCR 技术,我一直在使用以下代码:

在测试期间,我想测试 catch close,所以我向 Tesseract 提供了错误的信息,这应该会导致 TesseractException。 我设法从 createDocuments() 方法中引入了 TesseractException。 这是堆栈跟踪:

请注意,在异常中我们可以找到 doOcr() 的 line 125,它位于 try-catch 子句中,但即使控制台显示 TesseractException 被抛出,代码也会移动到 line 126 返回 true。

我使用 net.sourceforge.tess4j.Tesseract 来启动 OCR 过程,但我也尝试了 net.sourceforge.tess4j.Tesseract1,这导致了与 Tess4j 相同的红色控制台输出,但没有 TesseractException

我的问题是我做错了什么?我只是假设我的代码有问题,因为 TesseractException 被抛出,但我的代码没有捕捉到它。

查看Tesseract.java的源码:

@Override
public void createDocuments(String[] filenames, String[] outputbases, List<RenderedFormat> formats) throws TesseractException {
    if (filenames.length != outputbases.length) {
        throw new RuntimeException("The two arrays must match in length.");
    }

    init();
    setTessVariables();

    try {
        for (int i = 0; i < filenames.length; i++) {
            File workingTiffFile = null;
            try {
                String filename = filenames[i];

                // if PDF, convert to multi-page TIFF
                if (filename.toLowerCase().endsWith(".pdf")) {
                    workingTiffFile = PdfUtilities.convertPdf2Tiff(new File(filename));
                    filename = workingTiffFile.getPath();
                }

                TessResultRenderer renderer = createRenderers(outputbases[i], formats);
                createDocuments(filename, renderer);
                api.TessDeleteResultRenderer(renderer);
            } catch (Exception e) {
                // skip the problematic image file
                logger.error(e.getMessage(), e);
            } finally {
                if (workingTiffFile != null && workingTiffFile.exists()) {
                    workingTiffFile.delete();
                }
            }
        }
    } finally {
        dispose();
    }
}

/**
 * Creates documents.
 *
 * @param filename input file
 * @param renderer renderer
 * @throws TesseractException
 */
private void createDocuments(String filename, TessResultRenderer renderer) throws TesseractException {
    api.TessBaseAPISetInputName(handle, filename); //for reading a UNLV zone file
    int result = api.TessBaseAPIProcessPages(handle, filename, null, 0, renderer);

    if (result == ITessAPI.FALSE) {
        throw new TesseractException("Error during processing page.");
    }
}

在第 579 行抛出异常。此方法由上面的 public 方法调用 - 在第 551 行。这是在 try-catch 块内,捕获体中有 logger.error(e.getMessage(), e); (第 555 行)。

现在的问题是你真正想要达到的目标是什么?

如果不想看到这个日志,可以配置slf4j不打印这个库的日志。

如果你想得到真正的异常,这是不可能的,因为库吞噬了它。我不熟悉这个库,但看代码似乎没有任何好的选择——抛出异常的方法是私有的,只在这个地方使用——在 try-catch 块下.但是,当 api.TessBaseAPIProcessPages(...) returns ITessAPI.FALSEapi 有一个 getter 时抛出异常。所以你可以得到它,调用 TessBaseAPIProcessPages(...) 方法并检查结果。这可能并不理想,因为您可能会对每个图像处理两次。另一种解决方案是 fork 源代码并自行修改。您可能还想联系作者并寻求建议 - 您可以更进一步并提交拉取请求以供他们批准和发布。

将 pdf.ttf 文件添加到 tessdata 路径 (tessdata/pdf.ttf) pdf.ttf