我是Apache的PDFBox的新手 . 我正在使用从svn存储库获取的2.0.0版 . 实际上我尝试增加PDPage对象的cropbox . 好的,没有挑战 . 但页面内容仍保留在裁剪框的左下角 . 我希望它集中在新的cropbox空间 .
我知道所有内容都绝对以PDF格式定位 . 所以我的问题是:有没有办法使用PDFBox来翻译我的PDPage的原点(x,y)或内容元素?
问候汉斯
第一种方法是简单地更改裁剪框,如下所示:
PDDocument document = PDDocument.load(new File("data/test.pdf")); PDDocumentCatalog catalog = document.getDocumentCatalog(); @SuppressWarnings("unchecked") List<PDPage> pages = catalog.getAllPages(); float expand = 72; for (PDPage page : pages) { PDRectangle cropBox = page.findCropBox(); PDRectangle newCropBox = new PDRectangle(); newCropBox.setLowerLeftX(cropBox.getLowerLeftX() - expand); newCropBox.setLowerLeftY(cropBox.getLowerLeftY() - expand); newCropBox.setUpperRightX(cropBox.getUpperRightX() + expand); newCropBox.setUpperRightY(cropBox.getUpperRightY() + expand); page.setCropBox(newCropBox); } document.save("data/out/test-expand-crop-simple.pdf");
但这仅在某些情况下有效,因为根据规范ISO 32000-1,第14.11.2节“页面边界”
作物,出血,装饰和艺术盒通常不应超出媒体盒的边界 . 如果他们这样做,他们有效地减少到他们与媒体盒的交集 .
(另见this answer)
因此,我们必须确保即使在放大之后,裁剪框仍然适合于媒体盒,例如,像这样:
PDDocument document = PDDocument.load(new File("data/test.pdf")); PDDocumentCatalog catalog = document.getDocumentCatalog(); @SuppressWarnings("unchecked") List<PDPage> pages = catalog.getAllPages(); float expand = 72; for (PDPage page : pages) { PDRectangle cropBox = page.findCropBox(); PDRectangle newCropBox = new PDRectangle(); newCropBox.setLowerLeftX(cropBox.getLowerLeftX() - expand); newCropBox.setLowerLeftY(cropBox.getLowerLeftY() - expand); newCropBox.setUpperRightX(cropBox.getUpperRightX() + expand); newCropBox.setUpperRightY(cropBox.getUpperRightY() + expand); page.setCropBox(newCropBox); PDRectangle mediaBox = page.findMediaBox(); PDRectangle newMediaBox = new PDRectangle(); newMediaBox.setLowerLeftX(mediaBox.getLowerLeftX() - expand); newMediaBox.setLowerLeftY(mediaBox.getLowerLeftY() - expand); newMediaBox.setUpperRightX(mediaBox.getUpperRightX() + expand); newMediaBox.setUpperRightY(mediaBox.getUpperRightY() + expand); page.setMediaBox(newMediaBox); } document.save("data/out/test-expand-crop-and-media.pdf");
操作裁剪框的中心代码如下所示:
@Override protected void treeNodeChanged(PDFTreeNode node) { if (node instanceof PDFFloatNode) { PDFFloatNode nodeF = (PDFFloatNode)node; String strDataKey = node.getDataKey(); if ("x".equals(strDataKey)) { m_rect.setLowerLeftX(nodeF.getFloat()); } else if ("y".equals(strDataKey)) { m_rect.setLowerLeftY(nodeF.getFloat()); } else if ("width".equals(strDataKey)) { m_rect.setUpperRightX(nodeF.getFloat()); } else if ("height".equals(strDataKey)) { m_rect.setUpperRightY(nodeF.getFloat()); } } if (m_parent != null) { m_parent.treeNodeChanged(node); } }
其中m_rect是PDRectangle的一个实例 . 事实上,这些信息对你没有帮助,@ mkl . 在我之间我找到了解决问题的信息(我希望) . 有一个操作在PDFBox中显然是未知的 .
<</PageOffset [-20 20]>> setpagedevice
现在我正在寻找一种方法将其实现到PDF中 .
谢谢汉斯
Pageoffset字典条目不是很有帮助 . 它可以用作GhostScript的参数 . 但GS并没有真正创建一个字典条目 . 相反,它会抵消所有页面的内容 . PDFBox中不存在的功能 .
我找到了使用LayerUtility的解决方案:
PDDocument docIn = null; try { docIn = PDDocument.load("./pdf/Test1.pdf"); float fBorder = 10 * MM_TO_UNITS; // Arbitrary 10 mm PDDocument docOut = new PDDocument(); PDPage pageIn = (PDPage)docIn.getDocumentCatalog().getPages().getKids().get(0); PDRectangle rectCrop = pageIn.findCropBox(); PDPage pageClone = clonePage(docOut, pageIn, true), pageOut = new PDPage( new PDRectangle(rectCrop.getWidth() + 2 * fBorder, rectCrop.getHeight() + 2 * fBorder) ); docOut.addPage(pageOut); PDPageContentStream stream = new PDPageContentStream(docOut, pageOut); stream.close(); LayerUtility lu = new LayerUtility(docOut); lu.wrapInSaveRestore(pageOut); PDXObjectForm xobj = lu.importPageAsForm(docIn, pageClone); AffineTransform at = new AffineTransform(); // That's the point where x,y offset takes place at.setToTranslation(fBorder, fBorder); lu.appendFormAsLayer(pageOut, xobj, at, "layerx"); docOut.addPage(pageOut); docOut.save("./pdf/Test1out.pdf"); } finally { if (docIn != null) { docIn.close(); } }
我对此并不满意 . 因为它改变了页面结构 . 但至少我有一个解决方案 .
要增加CropBox,可以像这样设置MediaBox:
PDRectangle box = new PDRectangle(pageWidth, pageHeight); page.setMediaBox(box); // MediaBox > BleedBox > TrimBox/CropBox
4 回答
第一种方法是简单地更改裁剪框,如下所示:
但这仅在某些情况下有效,因为根据规范ISO 32000-1,第14.11.2节“页面边界”
(另见this answer)
因此,我们必须确保即使在放大之后,裁剪框仍然适合于媒体盒,例如,像这样:
操作裁剪框的中心代码如下所示:
其中m_rect是PDRectangle的一个实例 . 事实上,这些信息对你没有帮助,@ mkl . 在我之间我找到了解决问题的信息(我希望) . 有一个操作在PDFBox中显然是未知的 .
现在我正在寻找一种方法将其实现到PDF中 .
谢谢汉斯
Pageoffset字典条目不是很有帮助 . 它可以用作GhostScript的参数 . 但GS并没有真正创建一个字典条目 . 相反,它会抵消所有页面的内容 . PDFBox中不存在的功能 .
我找到了使用LayerUtility的解决方案:
我对此并不满意 . 因为它改变了页面结构 . 但至少我有一个解决方案 .
问候汉斯
要增加CropBox,可以像这样设置MediaBox: