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

sdm*_*ris 1 pdf pdfbox

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

mkl*_*mkl 5

在评论中已经指出,为了将一些内容(例如现有的常规肖像或风景页面)以任意角度绘制到新的常规肖像或风景页面上,可以使用该答案中呈现的机制.

正如那里提供的代码

  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);
    }
}
Run Code Online (Sandbox Code Playgroud)

将给定的转换应用于给定页面.为了使手上的用例(旋转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");
}
Run Code Online (Sandbox Code Playgroud)

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