首页 文章

如何翻译PDPage的x,y原点

提问于
浏览
1

我是Apache的PDFBox的新手 . 我正在使用从svn存储库获取的2.0.0版 . 实际上我尝试增加PDPage对象的cropbox . 好的,没有挑战 . 但页面内容仍保留在裁剪框的左下角 . 我希望它集中在新的cropbox空间 .

我知道所有内容都绝对以PDF格式定位 . 所以我的问题是:有没有办法使用PDFBox来翻译我的PDPage的原点(x,y)或内容元素?

问候汉斯

4 回答

  • 0

    第一种方法是简单地更改裁剪框,如下所示:

    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");
    
  • 0

    操作裁剪框的中心代码如下所示:

    @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中 .

    谢谢汉斯

  • 0

    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();
            }
        }
    

    我对此并不满意 . 因为它改变了页面结构 . 但至少我有一个解决方案 .

    问候汉斯

  • 0

    要增加CropBox,可以像这样设置MediaBox:

    PDRectangle box = new PDRectangle(pageWidth, pageHeight);
    page.setMediaBox(box); // MediaBox > BleedBox > TrimBox/CropBox
    

相关问题