PDF - 删除白边

时间:2012-05-02 15:44:00

标签: pdf pdf-generation itext ghostscript pypdf

我想知道一种从PDF文件中删除白边距的方法。就像Adobe Acrobat X Pro一样。我知道它不适用于每个PDF文件。

我猜这样做的方法是获取文本边距,然后裁剪出边距。

PyPdf是首选。

iText根据此代码查找文字边距:

public void addMarginRectangle(String src, String dest)
    throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfReaderContentParser parser = new PdfReaderContentParser(reader);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
    TextMarginFinder finder;
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        finder = parser.processContent(i, new TextMarginFinder());
        PdfContentByte cb = stamper.getOverContent(i);
        cb.rectangle(finder.getLlx(), finder.getLly(),
            finder.getWidth(), finder.getHeight());
        cb.stroke();
    }
    stamper.close();
}

2 个答案:

答案 0 :(得分:19)

我对PyPDF并不太熟悉,但我知道Ghostscript能够为你做到这一点。以下是关于类似问题的其他答案的链接:

  1. Convert PDF 2 sides per page to 1 side per page(SuperUser.com)
  2. Freeware to split a pdf's pages down the middle?(SuperUser.com)
  3. Cropping a PDF using Ghostscript 9.01(StackOverflow.com)
  4. 第三个答案可能就是让你说'我明白它不适用于每个PDF文件'的原因。它使用 pdfmark 命令尝试将/CropBox设置为PDF页面对象。

    前三个答案的方法很可能在第三个答案失败时成功。此方法使用<</PageOffset [NNN MMM]>> setpagedevice的PostScript命令片段将PDF页面移位并放置在-gNNNNxMMMM参数(定义设备宽度和高度,以像素为单位)定义的(较小)媒体大小上。

    如果您理解前两个答案背后的概念,您将能够轻松地调整其中使用的方法来裁剪PDF页面的所有4个边缘上的边距:

    一个示例命令,用于在4个边缘的每个边上裁剪一个字母大小的PDF(8.5x11in == 612x792pt)半英寸(== 36pt)(命令适用于Windows):

    gswin32c.exe ^
        -o cropped.pdf ^
        -sDEVICE=pdfwrite ^
        -g5400x7200 ^
        -c "<</PageOffset [-36 -36]>> setpagedevice" ^
        -f input.pdf
    

    结果页面大小为7.5x10英寸(== 540x720pt)。要在Linux或Mac上执行相同操作,请使用:

    gs \
        -o cropped.pdf \
        -sDEVICE=pdfwrite \
        -g5400x7200 \
        -c "<</PageOffset [-36 -36]>> setpagedevice" \
        -f input.pdf
    

    更新:如何使用Ghostscript确定'边距'

    评论要求“自动”确定白边。你也可以使用Ghostscript。它的bbox设备可以确定每个页面上(虚拟)墨水所覆盖的区域(因此,间接地确定画布每个边缘的空白)。

    这是命令:

    gs \
      -q -dBATCH -dNOPAUSE \
      -sDEVICE=bbox \
       input.pdf 
    

    输出(示例):

     %%BoundingBox: 57 29 562 764
     %%HiResBoundingBox: 57.265030 29.347046 560.245045 763.649977
     %%BoundingBox: 57 28 562 667
     %%HiResBoundingBox: 57.265030 28.347046 560.245045 666.295011
    

    bbox设备在内存中呈现每个PDF页面(不将任何输出写入磁盘),然后将BoundingBox和HiResBoundingBox信息打印到stderr。您可以像这样修改此命令,以使结果更容易解析:

    gs \
        -q -dBATCH -dNOPAUSE \
        -sDEVICE=bbox \
         input.pdf \
         2>&1 \  
      | grep -v HiResBoundingBox
    

    输出(示例):

     %%BoundingBox: 57 29 562 764
     %%BoundingBox: 57 28 561 667
    

    这会告诉你......

    • ... Page 1 内容矩形的左下角位于坐标[57 29],右上角位于[562 741]
    • ... Page 2 内容矩形的左下角位于坐标[57 28]处,右上角位于[561 667]

    这意味着:

    • 第1页在左边缘使用了57pt的空格(72pt == 1in == 25,4mm)。
    • 第1页在底部边缘使用了29pt的空格。
    • 第2页在左边缘使用57pt的空格。
    • 第2页在底部边缘使用了28pt的空格。

    正如您已经从这个简单示例中看到的那样,每个页面的空白并不完全相同。根据您的需要(您可能希望多页PDF的每一页都有相同的大小,不是吗?),您必须计算出文档所有页面中每条边的最小边距。

    现在右边和上边缘的空白怎么样?要计算,您需要知道每个页面的原始页面大小。确定这一点的最简单方法是:pdfinfo实用程序。 5页PDF的示例命令:

    pdfinfo \
      -f 1 \
      -l 5 \
       input.pdf \
    | grep "Page "
    

    输出(示例):

    Page    1 size: 612 x 792 pts (letter)
    Page    2 size: 612 x 792 pts (letter)
    Page    3 size: 595 x 842 pts (A4)
    Page    4 size: 842 x 1191 pts (A3)
    Page    5 size: 612 x 792 pts (letter)
    

    这将帮助您确定所需的画布大小以及每个新PDF页面的顶部和右侧边缘所需的(最大)白色边距。

    当然,这些计算都可以编写脚本。

    但是如果您的PDF文件都是uniq页面大小,或者它们是1页文档,那么这一切都更容易完成......

答案 1 :(得分:8)

试试pdfcrop。它需要ghostscript。