简而言之
我一直在做一个程序,可以得到一个pdf,突出显示一些单词(通过pdfbox Mark注释)并保存新的pdf。
为了使这些注释在一些查看器(如pdf)上可见。js,需要调用pdAnnotationTextMarkup。constructAppearances(),然后将标记批注添加到页面批注列表中。
但是,这样做的话,在处理包含数千个标记注释的大型文档时,我会得到一个OutOfMemoryError。
我想知道是否有办法防止这种情况发生。
(这是这张票的续集,但与这张无关)
技术规格:
PDFBox 2.0.17
Java11.0.6 10, AdoptOpenJDK
MacOS Catalina 10.15.2,16gb,x86_64
我的代码
//my pdf has 216 pages
for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++) {
PDPage page = document.getPage(pageIndex);
List<PDAnnotation> annotations = page.getAnnotations();
// each coordinate obj represents a hl annotation. crashing with 7.816 elements
for (CoordinatePoint coordinate : coordinates) {
PDAnnotationTextMarkup txtMark = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
txtMark.setRectangle(pdRectangle);
txtMark.setQuadPoints(quadPoints);
txtMark.setColor(getColor());
txtMark.setTitlePopup(coordinate.getHintDescription());
txtMark.setReadOnly(true);
// this is what makes everything visible on pdf.js and what causes the Java heap space error
txtMark.constructAppearances();
annotations.add(txtMark);
}
}
当前结果
这是引出问题的重磅pdf文档:https://pdf host . io/v/I ~ nu ~ . 6g _ French _ Intensive _ Care _ Society _ International _ congress _ rani mation _ 2016 . pdf
我的程序尝试在整个216个页面中添加7.816个注释。
和堆栈跟踪:
[main] INFO highlight.PDFAnnotation - Highlighting 13613_2016_Article_114.pdf...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.apache.pdfbox.io.ScratchFile.<init>(ScratchFile.java:128)
at org.apache.pdfbox.io.ScratchFile.getMainMemoryOnlyInstance(ScratchFile.java:143)
at org.apache.pdfbox.cos.COSStream.<init>(COSStream.java:61)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDAbstractAppearanceHandler.createCOSStream(PDAbstractAppearanceHandler.java:106)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDHighlightAppearanceHandler.generateNormalAppearance(PDHighlightAppearanceHandler.java:136)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDHighlightAppearanceHandler.generateAppearanceStreams(PDHighlightAppearanceHandler.java:59)
at org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup.constructAppearances(PDAnnotationTextMarkup.java:175)
at org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup.constructAppearances(PDAnnotationTextMarkup.java:147)
at highlight.PDFAnnotation.drawHLAnnotations(PDFAnnotation.java:288)
我已经尝试将我的jvm xmx和xms参数增加到像< code>-Xmx10g -Xms10g这样,这只是稍微推迟了崩溃。
我想要的
我希望避免这个内存问题,并且仍然能够在pdf.js viewer中看到我的注释。如果不调用constructAppearances,这个过程会快得多,我没有这个问题,但是注释只能在一些pdf查看器上看到,比如Adobe。
有什么建议吗?我在这里做错了什么还是错过了什么?
在即将推出的 2.0.19 版本中,按如下方式构造外观:
annotation.constructAppearances(document);
在2.0.18及更早版本中,您需要自己初始化外观处理程序:
setCustomAppearanceHandler(new PDHighlightAppearanceHandler(annotation, document));
该行可以在2.0.19中删除,因为这是默认的外观处理程序。
为什么要这么做?这样文档公共内存空间(“临时文件”)就用在注释处理程序中,而不是每次都创建一个新的(很大)。后面的操作是在调用new COSStream()
而不是document.getDocument(). createCOSStream()
时完成的。
所有这些当然只有在做许多注释时才重要。
相关PDFBox问题:PDFBOX-4772和PDFBOX-4080
问题内容: 为什么有Java不允许覆盖静态方法?,它声称在Java中不允许覆盖静态方法。但这似乎在OpenJDK中有效: 在不使用时,可以编译这两个类,但在编译时会失败。要重现此文件,文件如下所示。 和这样的文件: 使用时,该错误是IS 当移除时,输出是所述的,方法。 javac是OpenJDK的版本。 错误在哪里?(理想情况是将其添加到静态方法中,但回答这是in的错误,或者我的想法也不错) 问题
我试图在Android Studio中使用Doclava为Android库生成Javadoc。源代码在某些时候使用了“Nullable”标记,这会在生成javadoc时导致崩溃: 在doclet类com中。谷歌。多克拉瓦。Doclava,方法start引发了一个异常java。朗。反思。调用TargetException com。太阳工具。javac。密码Symbol$CompletionFailu
问题内容: 在Jackson中,当您使用注释构造函数时,必须使用注释其参数。所以这个构造函数 变成这个: 我不明白为什么有必要。你能解释一下吗? 问题答案: Jackson必须知道以什么顺序将字段从JSON对象传递给构造函数。使用反射无法在Java中访问参数名称-这就是为什么您必须在注释中重复此信息的原因。
问题内容: 我正在尝试在我的项目中实现dagger2,但遇到错误“ android.app.Application必须在没有@Inject构造函数或@Provides注释方法的情况下才能提供 ”。 这是我的代码: App.java di / AppModule.java di / AppComponent.java di / TestClassModule.java di / TestClassC
我有一个自定义的参数解析器,它在Spring 3.0.7中工作,但在Spring 3.1.2中失败。下面显示堆栈跟踪和测试驱动程序代码。 当我查看堆栈跟踪时,似乎没有调用。相反,我在堆栈跟踪中看到。 建议? 最后...这里是Spring配置中的注释驱动标记
当我使用PDDocument和PDFTextStripper方法时,尽管导入了所有必需的库,但我还是收到了错误。