如何将PDF页面的内容旋转到任意角度?

问题描述 投票:0回答:2

我需要将 PDF 页面的内容旋转任意角度,而 PDPage.setRotation(int) 命令被限制为 90 度的倍数。 页面的内容是矢量和文本,我需要稍后能够放大内容,这意味着由于分辨率的损失,我无法将页面转换为图像。

java pdf pdfbox
2个回答
6
投票

在评论中已经指出要绘制一些内容,例如将现有的常规纵向或横向页面以任意角度放置到新的常规纵向或横向页面上,可以使用在此答案中中介绍的机制。

正如那里提供的代码

  1. 需要 PDFBox 开发 2.0.0-SNAPSHOT 版本并且
  2. 使用 xobjects 形式,这在当前上下文中是不必要的,

尽管如此,这里有一个适用于当前常规版本 1.8.8 的快速而肮脏的解决方案,无需引入 xobjects 形式。

这个方法

void transformPage(PDDocument document, PDPage page, AffineTransform at) throws IOException, COSVisitorException
{
    PDRectangle cropBox = page.findCropBox();
    float xOffset = (cropBox.getUpperRightX() + cropBox.getLowerLeftX()) / 2f;
    float yOffset = (cropBox.getUpperRightY() + cropBox.getLowerLeftY()) / 2f;
    AffineTransform transform = AffineTransform.getTranslateInstance(xOffset, yOffset);
    transform.concatenate(at);
    transform.concatenate(AffineTransform.getTranslateInstance(-xOffset, -yOffset));

    PDPageContentStream stream = new PDPageContentStream(document, page, true, false);
    stream.concatenate2CTM(transform);
    stream.close();

    COSBase contents = page.getCOSDictionary().getDictionaryObject(COSName.CONTENTS);
    if (contents instanceof COSStreamArray)
    {
        COSStreamArray contentsArray = (COSStreamArray) contents;
        COSArray newArray = new COSArray();
        newArray.add(contentsArray.get(contentsArray.getStreamCount() - 1));

        for (int i = 0; i < contentsArray.getStreamCount() - 1; i++)
        {
            newArray.add(contentsArray.get(i));
        }

        COSStreamArray newStreamArray = new COSStreamArray(newArray);
        page.getCOSDictionary().setItem(COSName.CONTENTS, newStreamArray);
    }
}

将给定的转换应用到给定的页面。为了使现有用例(旋转 PDF 页面的内容)更容易,转换包含在将坐标系原点移动到页面中心以进行转换的平移中。

方法可以这样用

try ( InputStream sourceStream = getClass().getResourceAsStream("13.pdf") )
{
    final PDDocument document = PDDocument.load(sourceStream);
    final AffineTransform transform = AffineTransform.getRotateInstance(Math.PI / 4);

    List<PDPage> pages = document.getDocumentCatalog().getAllPages();

    for (PDPage page: pages)
    {
        transformPage(document, page, transform);
    }

    document.save("13-transformedPages.pdf");
}

将文档页面逆时针旋转 45°(PI/4,数学上的正旋转方向)。


2
投票

请阅读 ISO-32000-1(这是 PDF 的 ISO 标准),更多特别是表 30(“页面对象中的条目”)。它定义了像这样的

Rotate
条目(文字复制/粘贴):

页面顺时针旋转的度数 显示或打印时。该值应为 90 的倍数。 默认值:0。

每当 ISO 标准使用“应”一词时,您都会遇到规范性规则(与标准使用“应该”一词相反,在这种情况下您会面临建议)。 简而言之:您所询问的问题是 PDF 规范明确禁止的。在 PDF 中满足您的要求是不可能的。您的页面方向可以为 0、90、180 或 270 度。您必须旋转页面上的内容,而不是旋转页面。

© www.soinside.com 2019 - 2024. All rights reserved.