Tesseract - 错误 net.sourceforge.tess4j.Tesseract - null
Posted
技术标签:
【中文标题】Tesseract - 错误 net.sourceforge.tess4j.Tesseract - null【英文标题】:Tesseract - ERROR net.sourceforge.tess4j.Tesseract - null 【发布时间】:2017-01-23 01:49:09 【问题描述】:创建了一个使用 Tesseract 的 java 应用程序,以便将给定的图像或 pdf 转换为字符串格式,当使用 junit 在我的机器上作为单元测试运行它时,它运行良好,但是当运行完整的系统时,它是一个 restFul API由接收图像并运行 Tesseract 的 tomcat 运行它给我以下错误:
23:22:36.511 [http-nio-9999-exec-3] 错误 net.sourceforge.tess4j.Tesseract - null java.lang.NullPointerException:空在 net.sourceforge.tess4j.util.PdfUtilities.convertPdf2Png(PdfUtilities.java:107) 在 net.sourceforge.tess4j.util.PdfUtilities.convertPdf2Tiff(PdfUtilities.java:48) 在 net.sourceforge.tess4j.util.ImageIOHelper.getIIOImageList(ImageIOHelper.java:343) 在 net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:213) 在 net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:197) 在 ocr.OcrUtil.getString(OcrUtil.java:54) 在 com.tapd.server.api.handlers.IRSHandler.uploadIRSImage(IRSHandler.java:65) 在 com.tapd.server.api.WebAPIService.updateParentIrsForm(WebAPIService.java:250) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)在 java.lang.reflect.Method.invoke(未知来源)在 org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) 在 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) 在 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) 在 org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) 在 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 在 org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 在 org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 在 org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 在 org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:309) 在 org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 在 org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 在 org.glassfish.jersey.internal.Errors.process(Errors.java:315) 在 org.glassfish.jersey.internal.Errors.process(Errors.java:297) 在 org.glassfish.jersey.internal.Errors.process(Errors.java:267) 在 org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 在 org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292) 在 org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1139) 在 org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:460) 在 org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386) 在 org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334) 在 org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在 org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110) 在 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 在 org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425) 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(未知来源)[2016-09-14 23:22:36,512] [错误] java.lang.NullPointerException
我的猜测是 tessdata 文件夹不在正确的位置,当打包成 Jar 并由 tomcat 运行时,它放错了位置,但我不知道它应该放在哪里,我已经仔细检查过所有的 jar 都被正确部署了。
编辑:所以看起来Tesseract在AWS S3等远程服务器上时无法处理路径,所以问题是为什么?以及如何允许它使用来自 S3 的路径? (是的,该文件是公开的)
【问题讨论】:
哪个版本的 Tesseract? 我使用 tess4j 3.2.1 版 你能显示Minimal, Complete, and Verifiable example吗? 哪个操作系统?如果不是 Windows,您是否安装了 GhostScript? 目前在 Windows 上运行,它将是 Linux 【参考方案1】:我的猜测是没有正确记录的 GhostscriptException,这导致了 NullPointerException:
https://github.com/nguyenq/tess4j/blob/212d72bc2ec8b3a4d4f5a18f1eb01a0622fc5521/src/main/java/net/sourceforge/tess4j/util/PdfUtilities.java#L107
106 catch (GhostscriptException e)
107 logger.error(e.getCause().toString(), e);
108 finally
在第 107 行 - e.getCause() (可能)为 null,调用 null.toString() 会引发 NPE。
(来自规范 - getCause 可以为空: https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#getCause(),GhostscriptException 也允许原因为空:http://grepcode.com/file/repo1.maven.org/maven2/org.ghost4j/ghost4j/1.0.0/org/ghost4j/GhostscriptException.java)
要验证这个答案(无需重新编译整个 tess4j),您可以在调试模式下启动程序并在第 107 行放置一个断点。这将为您提供有关真正异常的信息。
【讨论】:
我建议在 OP 的代码中将e.getCause().toString()
替换为 String.valueOf(e.getCause())
以确保在这种情况下安全。
我设法了解 GhostscriptException 为空,但真正的问题是为什么?我该如何解决?为什么当我在本地(junit)运行它时它不会发生?
“了解 GhostscriptException 为空” - 这是不正确的。 GhostscriptException 不为 null,GhostscriptException 是 Exception 的有效实例。只有 ghostscriptException.getCause() 为空。要解决此问题,请在调试模式下启动您的应用并检查异常消息是什么 - 应该有更多详细信息。
要完全解决这个问题,您必须针对 tess4j 提出一个错误:github.com/nguyenq/tess4j/issues(并且可能发送一个拉取请求)。如果您需要一些关于如何临时解决此问题的额外指导,您可以在聊天中给我打电话
@Axel - 这里的问题是它是第三方库(修复此错误需要 PR)【参考方案2】:
正如@Piotr R 提到的错误是ghostscriptException.getCause() 为null,原因是发送到Tesseract 的文件对象中配置的路径不是有效路径,现在Tesseract 的有效定义是与你的有点不同,他认为只有本地地址是有效的,所以在设置位于 AWS S3 上的文件时,即使它是公共的,它也会引发错误。 解决方案是将其保存在本地并在 Tesseract 完成后将其删除。
【讨论】:
@Piotr RI 没有 GhostscriptException 的堆栈跟踪,我也无法调试它,因为它是一个外部库,我访问 s3 的方式不相关,因为它无法访问不是存储在本地,这正是我正在寻找的答案和解决方案。话虽如此,我非常感谢您的帮助和支持,当我将自己标记为正确答案时不要担心,我没有得到赏金。【参考方案3】:我使用的资源:Windows 10(也在 Windows Server 2016 上试用过)、JAVA、MAVEN
状态:在我的本地和虚拟机上运行良好
-
从这里http://tess4j.sourceforge.net/ 下载 Tess4J-3.4.8 并在 Advance System Setting 下设置您的 ENV 变量路径
从 MAVEN 获取 repo -
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>org.ghost4j</groupId>
<artifactId>ghost4j</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.lept4j</groupId>
<artifactId>lept4j</artifactId>
<version>1.7.0</version>
</dependency>
获取 libtesseract302.dll 并复制到“C:\Windows\System32”文件夹 从这里http://api.256file.com/libtesseract302.dll/en-download-56466.html 不要忘记在高级系统设置下设置您的 ENV 变量路径
下载并安装 Visual C++ 2015 Redistributable 或 VC++ 2017 Redistributable(我都安装了) 从这里https://programmer.help/blogs/net.sourceforge.tess4j.tesseractexception-java.lang.nullpointerexception.html
然后重启你的电脑
如果您在本地没有 Jar 文件,则在更安全的一侧可以有一些 Jar 文件 - 请查看图片
不要忘记在高级系统设置下为 JAR 设置 ENV 变量路径
【讨论】:
以上是关于Tesseract - 错误 net.sourceforge.tess4j.Tesseract - null的主要内容,如果未能解决你的问题,请参考以下文章
错误!找不到命令“tesseract”。 (PHP 蒂亚戈莱西奥)
Tesseract 4.1.1 错误 eng.traineddata 在谷歌 colab 中找不到