我使用this technique将 acroform 从另一个源 pdf 导出到新的 pdf 文件。
结果 pdf 与 acroform 只有你可以 download here
我使用pdfcompressor在线网站来压缩这个pdf(59Ko),并将其缩小-64%。 这个网站似乎清理了资源中所有未使用的东西,这是 PDFDebugger 的屏幕截图
我的问题是,如果不从资源[]中删除它,如何从资源[]中获取xobject或字体并检查它们是否在页面中的某个位置使用。
如果在PDPage中搜索某些资源是否被使用或未使用很复杂,我如何简单地从Resources[]中删除XObject或Font?
虽然在页面中搜索使用过的 xobject 超出了我的范围,但我只是尝试直接删除 COSObject,但它不起作用 ^^ :
for (PDPage page : document.getPages()) {
PDResources resources = page.getResources();
// all xobject form resources
for (COSName name : resources.getXObjectNames()) {
page.getCOSObject().removeItem(name); // NOT WORKS
}
// all font resources from pages
for (COSName name : resources.getFontNames()) {
if (resources.getFont(name) instanceof PDFont) {
page.getCOSObject().removeItem(name); // NOT WORKS
}
}
}
ps:@mkl推荐后创建的问题discussed here
更新1
这是我必须从 pdf 中提取 acroform 的当前代码: //从原始创建 FORM
PDDocument documentSrc = PDDocument.load(new File("original.pdf"));;
PDAcroForm acroFormSrc = documentSrc.getDocumentCatalog().getAcroForm();
PDDocument documentDest = new PDDocument();
for (PDPage page : documentSrc.getPages()) {
PDPage destPage = new PDPage(PDRectangle.A4);
destPage.setMediaBox(page.getMediaBox());
destPage.setCropBox(page.getCropBox());
documentDest.addPage(destPage);
}
PDAcroForm acroFormDest = new PDAcroForm(documentDest);
acroFormDest.setCacheFields(true);
acroFormDest.setFields(acroFormSrc.getFields());
documentDest.getDocumentCatalog().setAcroForm(acroFormDest);
int pageIndex = 0;
for (PDPage page : documentSrc.getPages()) {
documentDest.getPage(pageIndex).setAnnotations(page.getAnnotations());
// after disabling this size increase
//documentDest.getPage(pageIndex).setResources(page.getResources());
pageIndex++;
}
acroFormDest.setDefaultAppearance(acroFormSrc.getDefaultAppearance());
acroFormDest.setDefaultResources(acroFormSrc.getDefaultResources());
acroFormDest.setQ(acroFormSrc.getQ());
// this is disabled because setResources is disabled above
//removeLinksInPages(documentDest);
//removeTextInDocument(documentDest);
这次 form-without-resources 是 73Ko,而我原来的 pdf 是 75Ko。
最佳答案
减少页面对象的资源
嗯,我认为您当前的任务比您在问题中要求的要简单得多。我解读你的意思
I use this technique to export acroform to new pdf file from another source pdf.
暗示您实际上只想将 AcroForm 字段和功能从一个 PDF 转移到另一个 PDF,并且对原始文件的静态页面内容不感兴趣。
因此,您实际使用哪些页面资源这个问题的答案很简单:无!页面资源是您不感兴趣的静态内容(页面内容流中)中使用的资源。
因此,无需首先将页面资源复制到新文档中,只需删除该行即可
documentDest.getPage(pageIndex).setResources(page.getResources());
来自引用答案中的代码。
<小时/>顺便说一句:@Tilman 已经在对您用作模板的答案的评论中指出,感兴趣的资源是“acroform 的默认资源”,而不是页面资源。因此,您可能不仅想在 PDAcroForm
实例之间复制字段:
acroFormDest.setFields(acroFormSrc.getFields());
还有默认资源、默认外观和默认四边形
acroFormDest.setDefaultAppearance(acroFormSrc.getDefaultAppearance());
acroFormDest.setDefaultResources(acroFormSrc.getDefaultResources());
acroFormDest.setQ(acroFormSrc.getQ());
其他问题
引用错误页面的注释
This time form-without-resources is 73Ko while my original pdf is 75Ko.
深入研究一下“form-without-resources.pdf”,问题就变得清晰起来:
如您所见,您的字段小部件注释指向错误的页面!
P 值指定为
P dictionary (Optional except as noted below; PDF 1.3; not used in FDF files) An indirect reference to the page object with which this annotation is associated.
(ISO 32000-1, Table 164 – Entries common to all annotation dictionaries)
因此,您将目标页面的注释设置为源页面的注释,但这些注释的 P 值仍然引用源页面。因此,您可以通过此引用将源页面及其所有资源拖到新文档中。因此,结果文件并不比源文件小一点也不奇怪。
如果您更改代码以更正P引用,例如像这样:
int pageIndex = 0;
for (PDPage page : documentSrc.getPages()) {
PDPage destPage = documentDest.getPage(pageIndex);
destPage.setAnnotations(page.getAnnotations());
for (PDAnnotation annotation : destPage.getAnnotations())
annotation.setPage(destPage);
// after disabling this size increase
//documentDest.getPage(pageIndex).setResources(page.getResources());
pageIndex++;
}
( CopyForm 测试 testCopyLikeBeeImproved
)
您将丢失对旧数据的这些引用。
关于java - 通过页面搜索已使用的资源并将其删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55416144/