Apache PDFBox rotate PDImageXObject

你。 提交于 2019-12-10 21:36:57

问题


I'm playing around with the 2.0.0-SNAPSHOT, and I want to set the page to landscape and also rotate my picture. So I've done page.setRotation(90);

There seems to be a bug with using PDFBox and AffineTransform

This code doesn't do anything like I'd expect:

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 by itself squishes the image, and translate before rotate seems to scale the image huge.

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


回答1:


Don't do an extra translation, instead put the translation when creating the AT. Remember that the rotation is around the bottom-left axis, so add the width w to 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 draw the image twice, once normally and once rotated 90°, and positioned to the right. "/2" is used to scale 50%, you can of course use another factor. Note that "/2" is not used for the initial x position, because the (scaled) width is needed twice. Once to position to the old 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, for the page rotation.




回答2:


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 by itself squishes the image, and translate before rotate seems to scale the image huge.

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

It is not a bug, it simply is math. You merely have to be aware that if you have an AffineTransform at and then call at.translate(...) or at.rotate(...), you do not set the translation / rotation part of the affine transformation to the given values but instead replace your transformation by the composition of the former transformation and the translation / rotation.

This means that e.g.

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

is not the same as

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

as you might have expected, but instead

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

This is why Width and Height have to be tiny to keep the image on the page - translate(0.5, 1) pushes very far otherwise.

As the order in which you compose the transformation matters, you might be happier if you created your transformation in this 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 that the rotation is around the bottom-left, so this composition will rotate off-screen, too. Simply add h+20 to the x coordinate of the initial translation.



来源:https://stackoverflow.com/questions/26119794/apache-pdfbox-rotate-pdimagexobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!