我正在使用PDFBox并尝试旋转图像并使其在屏幕上正确定位。我使用的设计编辑器输出有关可能有用的图像的以下信息。
图像边界框左上角坐标(我使用左下方的坐标以更好地适应PDFBox坐标空间。)
以度为单位的图像旋转
图像宽度&高度
翻译似乎已关闭。
// Rotation
AffineTransform rotation = new AffineTransform();
rotation.rotate(Math.toRadians(360 - element.getAngle()),
element.getLeft() + scaledWidth/2,
adjustedYPos + scaledHeight/2);
stream.transform(new Matrix(rotation));
// Position & scale
AffineTransform mat = new AffineTransform(scaledWidth,
0,
0,
scaledHeight,
element.getLeft(),
adjustedYPos);
// Draw the final image
stream.drawImage(pdfImage, new Matrix(mat));
旋转基于图像的中心作为锚点。
答案 0 :(得分:2)
您可以使用以下代码正确定位图像:
void placeImage(PDDocument document, PDPage page, PDImageXObject image, float bbLowerLeftX, float bbLowerLeftY, float width, float height, float angle) throws IOException {
try ( PDPageContentStream contentStream = new PDPageContentStream(document, page, AppendMode.APPEND, true, true) ) {
float bbWidth = (float)(Math.abs(Math.sin(angle))*height + Math.abs(Math.cos(angle))*width);
float bbHeight = (float)(Math.abs(Math.sin(angle))*width + Math.abs(Math.cos(angle))*height);
contentStream.transform(Matrix.getTranslateInstance((bbLowerLeftX + .5f*bbWidth), (bbLowerLeftY + .5f*bbHeight)));
contentStream.transform(Matrix.getRotateInstance(angle, 0, 0));
contentStream.drawImage(image, -.5f*width, -.5f*height, width, height);
}
}
(PlaceRotatedImage实用工具方法)
此方法接受坐标,因为它们在PDF的上下文中是有意义的,即根据给定页面的默认用户空间坐标系统的坐标值和尺寸( y 值向上增加,原点任意但是相当经常在左下方),左下角给出的(边界)框,角度与逆时针弧度的数学一样......
如果您需要不同的参数,您可以相当容易地调整方法。如果你是获取边界框的左上角而不是左下角,您可以简单地将方法中确定的边界框高度减去bbHeight
,以计算此处使用的左下角 y 坐标。
您可以像这样使用此方法:
PDPage page = ...;
PDRectangle mediaBox = page.getMediaBox();
float bbLowerLeftX = 50;
float bbLowerLeftY = 100;
try ( PDPageContentStream contentStream = new PDPageContentStream(document, page) ) {
contentStream.moveTo(bbLowerLeftX, mediaBox.getLowerLeftY());
contentStream.lineTo(bbLowerLeftX, mediaBox.getUpperRightY());
contentStream.moveTo(mediaBox.getLowerLeftX(), bbLowerLeftY);
contentStream.lineTo(mediaBox.getUpperRightX(), bbLowerLeftY);
contentStream.stroke();
}
PDImageXObject image = PDImageXObject.createFromByteArray(document, IOUtils.toByteArray(resource), "Image");
placeImage(document, page, image, bbLowerLeftX, bbLowerLeftY, image.getWidth(), image.getHeight(), (float)(Math.PI/4));
placeImage(document, page, image, bbLowerLeftX, bbLowerLeftY, .5f*image.getWidth(), .5f*image.getHeight(), 0);
placeImage(document, page, image, bbLowerLeftX, bbLowerLeftY, .25f*image.getWidth(), .25f*image.getHeight(), (float)(9*Math.PI/8));
(PlaceRotatedImage test testPlaceByBoundingBox
)
此代码绘制对应于给定左下边界框坐标左侧和底部的左下线,并以不同的放大倍数和角度绘制图像,并给出左下角边框的常数。
结果如下:
您可以在这些答案中找到有关计算边界框大小的更多信息: