Apache PDFBox rotates PDImageXObject

I am playing with 2.0.0-SNAPSHOT and I want the page to look like a landscape and also rotate the image. So I didpage.setRotation(90);

There seems to be a bug using PDFBox and AffineTransform

This code does nothing like this:

AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20);
at.translate(0.5, 1);
at.rotate(Math.toRadians(90));

      

Width and height have to be tiny in order to keep the image on the page, rotate on its own, twist the image and translate before rotation seems to scale the image.

Is this a bug or am I just not understanding PDFBox?

+3


source to share


2 answers


Don't do an additional translation, send the translation instead when you create an AT. Remember that rotation is around the bottom left axis, so add a width w at the x position.

    PDPage page = new PDPage();
    document.addPage(page);
    page.setRotation(90);
    PDPageContentStream contentStream = new PDPageContentStream(document, page);

    int x = 150;
    int y = 300;

    // draw unrotated
    contentStream.drawXObject(ximage, x, y, ximage.getWidth() / 2, ximage.getHeight() / 2);

    // draw 90° rotated, placed on the right of the first image
    AffineTransform at = new AffineTransform(ximage.getHeight() / 2, 0, 0, ximage.getWidth() / 2, x + ximage1.getWidth(), y);
    at.rotate(Math.toRadians(90));
    contentStream.drawXObject(ximage, at);

      



This will result in the reverse image twice, as usual, and rotated 90 ° and positioned to the right. "/ 2" is used for 50% scaling, you can of course use another factor. Note that "/ 2" is not used for the starting x position, because the (scaled) width is required twice. Once to place it back in position (because of the axis!) And once to move it to the right so that the images don't overlap.

Note also that getHeight () and getWidth () are reversed to rotate the page.

+3


source


AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20);
at.translate(0.5, 1);
at.rotate(Math.toRadians(90));

      

Width and height have to be tiny to keep the image on the page, rotate on its own, twist the image and translate before rotating it seems to scale the image huge.

Is this a bug or am I just not understanding PDFBox?

This is not a mistake, it is just math. You just need to know that if you have AffineTransform at

and then at.translate(...)

or is called at.rotate(...)

, you are not setting the translation / rotation part of the affine transformation to the given values, but instead replace your transformation with the composition of the first transformation and translation / rotation.

This means that, for example,

AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20);
at.translate(0.5, 1);

      

does not match

AffineTransform at = new AffineTransform(w, 0, 0, h, 20.5, 21);

      



as you might expect, but instead of

AffineTransform at = new AffineTransform(w, 0, 0, h, 20 + w/2, 20 + h);

      

This is why the width and height need to be tiny in order to keep the image on the page - translate(0.5, 1)

pushes a lot forward.

How the order in which you compose the transformation might be happier if you created your transform in the following order:

AffineTransform at = AffineTransform.getTranslateInstance(0.5, 1);
at.rotate(Math.toRadians(90));
af.concatenate(new AffineTransform(w, 0, 0, h, 20, 20));

      

PS: As Tilman said: Remember the rotation is around the lower left, so this composition will rotate offscreen too. Just add h+20

to the x coordinate of the original translation.

+1


source







All Articles