为了账号安全,请及时绑定邮箱和手机立即绑定

PDFBox - 插入第二张图像后的“saveIncremental”不起作用

PDFBox - 插入第二张图像后的“saveIncremental”不起作用

莫回无 2022-11-10 15:02:48
我在使用 PDFBox 时遇到问题。我在 PDF 中有一个空白页,我想在其中插入图像。因为我也使用签名的 PDF,所以所有更改都必须保存为“saveIncremental”。当我只插入一张图片时,一切都很好(图片已插入)。当我尝试在此 PDF 中插入另一个图像时,它尚未插入,并且在 Adobe Acrobat Reader 中打开时显示“此页面上存在错误。Adobe 可能无法正确显示页面......”。奇怪的事情 - 当 PDF 不仅是空白页,而且例如带有图像的空白页时,一切都很好(第一个和第二个图像已使用 saveIncremental 正确插入)。插入和保存图像的代码:PDImageXObject pdImage = PDImageXObject.createFromFile(tmpSig.getFileName(), doc);PDPageContentStream contentStream = new PDPageContentStream(doc, tmpPage, PDPageContentStream.AppendMode.APPEND, true, true);contentStream.drawImage(pdImage, finalX, (finalPageHeight - finalY - finalHeight), finalWidth, finalHeight);contentStream.close();// update before savetmpPage.getCOSObject().setNeedToBeUpdated(true);tmpPage.getResources().getCOSObject().setNeedToBeUpdated(true);doc.getDocumentCatalog().getPages().getCOSObject().setNeedToBeUpdated(true);doc.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);// savedoc.saveIncremental(new FileOutputStream(pdfFile));此处提供的所有文件使用 PDFBox 2.0.7 版,但我也尝试了最新的(2.0.15),但没有帮助。感谢所有的想法!编辑:我尝试像这样更新 XObject 和资源(在注释“保存前更新”下添加了此代码):pdImage.getCOSObject().setNeedToBeUpdated(true);PDResources pdResources = tmpPage.getResources();for (COSName name : pdResources.getXObjectNames()) {    pdResources.getXObject(name).getCOSObject().setNeedToBeUpdated(true);}问题仍然存在,没有任何改变......
查看完整描述

1 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

除了您已标记为已更新的词典


tmpPage.getCOSObject().setNeedToBeUpdated(true);

tmpPage.getResources().getCOSObject().setNeedToBeUpdated(true);

doc.getDocumentCatalog().getPages().getCOSObject().setNeedToBeUpdated(true);

doc.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);

还请将资源字典中的XObject条目标记为已更新:


tmpPage.getResources().getCOSObject().getCOSDictionary(COSName.XOBJECT).setNeedToBeUpdated(true);

您想知道为什么在添加第一张图片时不需要这样做吗?

在原始 PDF 中,资源字典中还没有XObject条目。因此,它是重新生成的,因此隐式标记为更新。


您想知道为什么在添加到已经有图像的文件时不需要这样做?

在那个其他文件中,资源字典中的XObject条目是直接对象,即它立即包含在资源字典中。


4 0 obj

<<

  /Type /Page

  /Resources <<

    /ProcSets [/PDF /Text /ImageB /ImageC /ImageI]

    /ExtGState <</G3 5 0 R /gs2 6 0 R /gs3 7 0 R>>

    /XObject <</Im1 8 0 R /Im2 9 0 R>>

  >>

  /MediaBox [0 0 611.03998 864.95996]

  /Contents [10 0 R 11 0 R 12 0 R 13 0 R 14 0 R]

  /StructParents 0

  /Parent 2 0 R

>> 

endobj

因此,每当写入资源字典的新副本时,也会隐含地写入XObject条目的新副本。


但是,在 PDFBox 在资源字典中创建XObject条目的文件中,PDFBox 将其创建为间接对象,即在资源字典中 XObject仅映射到对对象编号的引用,而在具有该编号的对象中实际条目字典可以查到。


2 0 obj

<<

  /Type /Page

  /Resources <<

    /ProcSets [/PDF /Text /ImageB /ImageC /ImageI]

    /ExtGState <</G3 3 0 R>>

    /XObject 7 0 R

  >>

  /MediaBox [0 0 611.03998 864.95996]

  /Contents [8 0 R 4 0 R 9 0 R]

  /StructParents 0

  /Parent 5 0 R

>>

endobj

7 0 obj

<<

  /Im1 10 0 R

>> 

endobj

因此,当写入资源字典的新副本时,在这种情况下不会写入XObject条目字典的隐式新副本。


顺便说一句,您当前的方法不会帮助您完成任务


因为我也使用签名的 PDF,所以所有更改都必须保存为“saveIncremental”。


向页面内容添加图像是不允许对已签名 PDF 进行的更改,因此 Adobe Reader 仍会指示您的签名无效。有关签名后允许和不允许的更改的摘要,请查看此答案和从中引用的文档。


您应该尝试在注释中添加图像。


查看完整回答
反对 回复 2022-11-10
  • 1 回答
  • 0 关注
  • 118 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信