如何翻译PDPage的x,y原点

时间:2013-12-20 13:56:10

标签: pdfbox

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

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

此致 汉斯

4 个答案:

答案 0 :(得分: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中。

由于 汉斯

答案 1 :(得分: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();
        }
    }

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

此致 汉斯

答案 2 :(得分: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");

答案 3 :(得分:0)

要增加CropBox,请按以下方式设置MediaBox:

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