我正在尝试使用PDFBox将pdf文件的第一页转换为图像。当我加载一个大的pdf文件时,我得到了一个异常。
代码:
PDDocument doc;
try {
InputStream input = new URL("http://www.jewishfederations.org/local_includes/downloads/39497.pdf").openStream();
doc = PDDocument.load(input);
PDPage firstPage = (PDPage) doc.getDocumentCatalog().getAllPages().get(0);
BufferedImage image =firstPage.convertToImage();
File outputfile = new File("image2.png");
ImageIO.write(image, "png", outputfile);
input.close();
doc.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}例外:
org.apache.pdfbox.pdfparser.BaseParser parseCOSStream
WARNING: Specified stream length 72435 is wrong. Fall back to reading stream until 'endstream'.
org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 72435 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize
at org.apache.pdfbox.pdfparser.BaseParser.parseCOSStream(BaseParser.java:554)
at org.apache.pdfbox.pdfparser.PDFParser.parseObject(PDFParser.java:605)
at org.apache.pdfbox.pdfparser.PDFParser.parse(PDFParser.java:194)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1219)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1186)
at Worker.main(Worker.java:27)
Caused by: java.io.IOException: Push back buffer is full
at java.io.PushbackInputStream.unread(Unknown Source)
at org.apache.pdfbox.io.PushBackInputStream.unread(PushBackInputStream.java:144)
at org.apache.pdfbox.io.PushBackInputStream.unread(PushBackInputStream.java:133)
at org.apache.pdfbox.pdfparser.BaseParser.parseCOSStream(BaseParser.java:550)
... 5 more发布于 2015-06-11 20:20:17
1.8.* PDFBox版本的另一种解决方案是使用非顺序解析器。在这种情况下,代码不会是
doc = PDDocument.load(input);但
doc = PDDocument.loadNonSeq(input, null);该解析器(将是即将到来的2.0版本中的唯一解析器)独立于推回缓冲区的大小。
发布于 2015-02-26 14:04:31
首先,找到当前的缓冲区大小:
System.out.println(System.getProperty("org.apache.pdfbox.baseParser.pushBackSize"));现在你已经有了一个基线,完全按照它的建议去做。使用以下命令将缓冲区大小增加到您刚才打印的大小之上:
System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "<buffer size>");不断增加缓冲区的大小,直到它起作用。如果你增加了heap,希望你不会耗尽内存。
这就是在运行时设置系统属性的方式。您也可以将其作为参数传递,但我发现在main的开头设置会起到作用,并使未来的开发人员更容易维护项目。
无论出于什么原因,对于大文件,您没有足够大的缓冲区来加载页面。也许页面在渲染为图像之前或同时被加载到缓冲区中。我的猜测是PDF中的DPI非常高,无法放入缓冲区。
发布于 2018-01-17 09:06:40
我也遇到过类似的问题,我认为这与一个基于错误的大型pdf文件有关,但事实证明并非如此。它原来是一个损坏的pdf文件。
对于我们的用例,我们有一个pdf模板文件(我们以编程方式填充它的表单值)作为我们项目中的一个资源,该资源被放入我们的war中。
我看到的可供参考的异常是:org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 480478 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize。我们添加了属性,然后再次运行,我们得到了一个不同的问题。
下一个堆栈跟踪指出“无法读取字体TimesNewRoman的嵌入式TTF,粗体”。我们花了一段时间,然而,在销毁war并尝试在war中打开pdf文件后,我们注意到它已损坏,但源代码中的pdf文件并未损坏,可以正常打开。
问题的根本原因是我们在pom中为我们的资源文件夹添加了“过滤”。我们这样做是为了可以使用一些反射来获取健康检查页面中的一些值,但这会损坏pdf文件,我们从下面的参考中发现了这一点:https://bitbucket.org/petermr/xhtml2stm/issues/12/pdf-files-are-being-corrupted-at-some
下面是我们设置的过滤的一个例子:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>我们的解决方案是将其从我们的pom中删除,并重新设计我们获取健康页面信息的方式。
https://stackoverflow.com/questions/22946079
复制相似问题