PDF缩小导致方向变化

时间:2018-02-03 19:22:20

标签: java itext pdf-generation

我正在使用以下代码缩小pdf。缩小PDF页面之前可以在Portrait中看到,但缩小后,它们的方向将变为横向。在收缩之前打印页面的旋转,它是270度。收缩后导致页面旋转的原因是什么? (我试图收缩的PDF有旧的扫描图像)

public  void shrinkPDF(String strFilePath , String strFileName) throws Exception {      
    PdfReader reader = new PdfReader(strFilePath+"//"+strFileName);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(strFilePath+"//Shrink_"+strFileName));
    int n = reader.getNumberOfPages();
    for (int p = 1; p <= 1; p++) {
        float offsetX = (reader.getPageSize(p).getWidth() * (1 - xPercentage)) / 2;
        float offsetY = (reader.getPageSize(p).getHeight() * (1 - yPercentage)) / 2;
        PdfDictionary page;
        PdfArray crop;
        PdfArray media;
        page = reader.getPageN(p);
        System.out.println("reader.getPateRoatation-->"+reader.getPageRotation(p));
        media = page.getAsArray(PdfName.CROPBOX);
        if (media == null) {
            media = page.getAsArray(PdfName.MEDIABOX);
        }
        crop = new PdfArray();
        crop.add(new PdfNumber(0));
        crop.add(new PdfNumber(0));
        crop.add(new PdfNumber(media.getAsNumber(2).floatValue()));
        crop.add(new PdfNumber(media.getAsNumber(3).floatValue()));
        page.put(PdfName.MEDIABOX, crop);
        page.put(PdfName.CROPBOX, crop);
        Rectangle mediabox = reader.getPageSize(p);
        stamper.getUnderContent(p).setLiteral(
                String.format("\nq %s %s %s %s %s %s cm\nq\n",
                xPercentage, mediabox.getLeft(),mediabox.getBottom(), yPercentage,  offsetX, offsetY));
        stamper.getOverContent(p).setLiteral("\nQ\nQ\n");           
    }
    stamper.close();
    reader.close();
}

1 个答案:

答案 0 :(得分:0)

原因

问题的原因是iText的一个特点:

iText尝试通过使用当前转换矩阵的旋转启动过度内容和内容不足来简化向旋转页面添加信息的过程。这使得页面的添加在PDF查看器中直立显示,而无需添加单独的旋转。

即使在原始页面内容之前绘制了内容不足,这通常也不会影响原始内容,因为整个内容都被包含在save-graphics-state / restore-graphics-state指令对中。

但是,您用作内容不足的文字包含两个保存图形状态指令,而不包含恢复图形状态指令。这使得添加的旋转也突然影响原始内容。因此,即使您只想缩放,也会旋转原始内容。

修复

iText允许您关闭上述功能。您可以在创建PdfStamper之后立即将RotateContents属性false设置为PdfStamper来实现此目的:

PdfStamper stamper = new PdfStamper(reader, result);
stamper.setRotateContents(false);
int n = reader.getNumberOfPages();

现在iText不再将这种旋转添加到内容中,只会缩放原始内容。

this answer中已经更深入地讨论了PdfStamper属性RotateContents

注释注意事项

iText不仅会将轮播添加到页面内容流的内容不足和过度内容中,还会操纵添加到旋转页面的注释的维度,遗憾的是,PdfStamper属性RotateContents未被考虑在内为此。

在这种情况下,解决方法是在将注释添加到页面之前临时删除页面旋转条目,并在以后再次将其重新放回。这已在this answerthis answerthis answer中进行了更详细的讨论。

您剩余的代码

  • 您对裁剪框和媒体框的更改似乎没有必要,可能会产生意外和不良后果。

  • 你可以像这样添加收缩:

    stamper.getUnderContent(p).setLiteral(
            String.format("\nq %s %s %s %s %s %s cm\nq\n",
            xPercentage, mediabox.getLeft(),mediabox.getBottom(), yPercentage,  offsetX, offsetY));
    

    将第二个和第三个参数分别设置为mediabox.getLeft()mediabox.getBottom()通常不会产生任何不良影响(因为这些值通常为0),但在某些情况下,您会遇到极其扭曲的视图(页面的放大部分)你的页面。