PDFBox - 获取旋转图像的边界框

PDFBox - obtain bounding box of rotated image

我正在使用 PDFBox 并尝试旋转图像并使其在屏幕上正确定位。我正在使用的设计编辑器输出以下可能有用的图像信息。

图像边界框左上角坐标(我使用左下角坐标来更好地适应 PDFBox 坐标 space。)

图像旋转度数

图片宽度和高度

翻译似乎有问题。

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

旋转是以图像的中心为锚点。

您可以使用如下代码正确定位图像:

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 上下文中有意义的坐标,即根据给定页面的默认用户 space 坐标系的坐标值和尺寸 (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 测试 testPlaceByBoundingBox)

此代码绘制与给定左下边界框坐标的左侧和底部相对应的左侧和底部线,并使用给定的左下边界框角以不同的放大倍率和角度绘制图像。

结果如下所示:


您可以在这些答案中找到有关计算边界框大小的更多信息:

  • Calculate Bounding box coordinates from a rotated rectangle
  • How to get width and height of the bounding box of a rotated rectangle
  • How to get size of a rotated rectangle
  • Find the Bounding Rectangle of Rotated Rectangle
  • ...