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

时间:2015-02-01 08:30:35

标签: pdf pdfbox

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

2 个答案:

答案 0 :(得分:5)

在评论中,已经指出绘制一些内容,例如现有的常规纵向或横向页面,以任意角度放置到新的常规纵向或横向页面上,可以使用呈现in this answer的机制。

正如那里提供的代码

  1. 需要PDFBox开发2.0.0-SNAPSHOT版本和
  2. 使用表格xobjects,在手边的上下文中没有必要,
  3. 但是,这里有一个快速而简单的解决方案,适用于当前的常规版本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,数学正向旋转方向)。

答案 1 :(得分:2)

请阅读ISO-32000-1(这是PDF的ISO标准),更多specifically Table 30 ("Entries in a page object")。它定义了这样的Rotate条目(文字复制/粘贴):

  

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

每当ISO标准使用 这个词时,你就会遇到一个规范性规则(相反,当标准使用这个词时,你面对的是推荐)。

简而言之:您正在询问PDF规范明确禁止的内容。在PDF中无法满足您的要求。您的页面可以具有0度,90度,180度或270度的方向。您必须旋转页面上的内容而不是旋转页面。