问题
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