簡體   English   中英

PDFBox-獲取旋轉圖像的邊界框

[英]PDFBox - obtain bounding box of rotated image

我正在使用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));

旋轉以圖像的中心為錨點。

您可以使用以下代碼正確定位圖像:

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測試testPlaceByBoundingBox

此代碼繪制與給定的左下邊界框坐標的左側和底部相對應的左和底線,並以給定的左下邊界框角的常數以不同的放大倍率和角度繪制圖像。

結果看起來像這樣:

截圖


您可以在以下答案中找到有關邊界框大小計算的更多信息:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM