2

I'm new to Apache's PDFBox. I'm using version 2.0.0, taken from the SVN repository.

Actually I try to increase the cropbox of a PDPage object. OK, no challenge. But the page content remains in the lower left corner of the cropbox. I want it centered in the new cropbox space.

I understood that all content is positioned absolutely in PDF. So my question: Is there a way using PDFBox to translate the origin (x, y) of my PDPage or the content elements?

Regards
Hans

informatik01
  • 16,038
  • 10
  • 74
  • 104
Hans
  • 33
  • 1
  • 4
  • It would be easier to just change the way you adjust your crop rectangle. Your wording suggests you are setting the width and height by changing UpperRightX/Y. Try changing LowerLeftX/Y as well. – Jongware Dec 20 '13 at 14:19
  • Did it already. But changing LowerLeft only changes the position of the cropbox in the mediabox. The page content remains in its position within the cropbox. – Hans Dec 20 '13 at 15:17
  • Please show the central code you use for crop box manipulation. – mkl Dec 20 '13 at 21:36
  • @ mkl, pls. see below – Hans Dec 20 '13 at 23:06
  • This link may be useful: http://stackoverflow.com/questions/28093537/in-pdfbox-how-to-change-the-origin-0-0-point-of-a-pdrectangle-object – Brian Jan 25 '15 at 05:13

4 Answers4

1

The first approach would be to simply change the crop box like this:

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

This only works sometimes, though, because according to the specification ISO 32000-1, section 14.11.2 Page Boundaries

The crop, bleed, trim, and art boxes shall not ordinarily extend beyond the boundaries of the media box. If they do, they are effectively reduced to their intersection with the media box.

(also see this answer)

Thus, we have to make sure that the crop box even after enlarging still fits into the media box, e.g. like this:

    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");
Community
  • 1
  • 1
mkl
  • 90,588
  • 15
  • 125
  • 265
  • Many thanks for your work, @mkl. This helped a lot. Adobe Reader shows the result fully correct. Now I have to find out what went wrong in my PageDrawer implementation. – Hans Dec 22 '13 at 09:33
  • Ok, my PageDrawer works now also correctly. And I found the reason why this went wrong. I saw the MediaBox as the source of the coordinate system. So my changes in the CropBox were always in the wrong direction. Many thanks Hans – Hans Dec 22 '13 at 11:33
  • @Hans That's great. If this essentially answered the original question, please accept as answer (on the left side of the answer you can mark it as accepted). – mkl Dec 22 '13 at 14:11
0

The central code to manipulate the crop box looks as follows:

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

Where m_rect is an instance of PDRectangle. In fact this information doesn't help you, @mkl. In between I found an information to solve the problem (I hope). There is an operation which is obviously not known in PDFBox.

<</PageOffset [-20 20]>> setpagedevice

Now I'm looking for a way to implement it into the PDF.

Thanks Hans

Hans
  • 33
  • 1
  • 4
  • *In fact this information doesn't help you* - correct. I have no idea what it is applied to... – mkl Dec 21 '13 at 15:30
0

The Pageoffset dictionary entry was not very helpful. It can be used as a parameter for GhostScript. But GS does not really create a dictionary entry. Instead it offsets the content of all pages. A capability which doesn't exist in PDFBox.

I found a solution using 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();
        }
    }

I'm not very happy with this. Because it changes the page structure. But at least I have a solution.

Regards Hans

Hans
  • 33
  • 1
  • 4
0

To increase the CropBox, you set the MediaBox like this:

PDRectangle box = new PDRectangle(pageWidth, pageHeight);
page.setMediaBox(box); // MediaBox > BleedBox > TrimBox/CropBox
Baked Inhalf
  • 3,375
  • 1
  • 31
  • 45
  • how doors this relate to the question? In particular why should changing the **MediaBox** in general change the **CropBox**? – mkl Dec 12 '17 at 21:29
  • "I try to increase the cropbox of a PDPage object". MediaBox is the outer limit of the pdf. It might not work this way in other sdk, but for pdfbox it does work – Baked Inhalf Dec 12 '17 at 22:15
  • *"but for pdfbox it does work"* - no generally. The crop box *defaults* to the media box. Thus, if there is no explicit crop box, your code makes a change via this default. But if there is an explicit crop box, only changing the media box in general is not enough for enlarging the crop box. – mkl Dec 12 '17 at 23:16
  • Not entirely true. I'm not PDF expert, but the implementation of pdfbox according to my experience, is how it works. You cannot increase the cropbox unless you first change the mediabox - also it WILL set the cropbox to the size of the mediabox, hence increase the size of the cropbox. – Baked Inhalf Dec 13 '17 at 08:51
  • *"You cannot increase the cropbox unless you first change the mediabox"* - your cannot effective increase the crop box beyond the media box. True. But your answer does not touch the crop box at all. *"it WILL set the cropbox to the size of the mediabox"* - nope, I just looked at the sources, it leaves the crop box untouched. (As mentioned before, though, if the crop box is not explicitly set, it *defaults* to the media box. Your comments sound like you only had to cope with such PDFs without explicit crop box settings. ) – mkl Dec 13 '17 at 10:41
  • Nope, I made a pdf, set cropbox, created an overlay from it, merging with an pre-made pdf. Unable to increase cropbox. When increasing the mediabox the cropbox followed, bam! Using Pdfbox 2.x. Listen, I don't know what you are trying here, but I layed out an answer for future visitors. It's highly related to the OP. This is just waste of time – Baked Inhalf Dec 13 '17 at 11:37
  • *"created an overlay"* - overlays usually don't have an explicit crop box anymore, so you are in the defaulting situation mentioned above. As conjectured in my previous comment, you indeed appear to only have had to cope with such PDFs without explicit crop box settings. *"I don't know what you are trying here"* - I'm trying to make clear for your *future visitors* that the answer works only under specific circumstances, namely only for pages without an explicit crop box setting. – mkl Dec 13 '17 at 12:29
  • You can create an overlay using a pre made pdf, or create your own with pdfbox. Have you even used pdfbox? Seems like you are applying your theory on how pdf work in general. And No, you are not making anything clear for future visitors, as your comments are based on assumptions and not fact. – Baked Inhalf Dec 13 '17 at 13:10