13

我想知道一种从 PDF 文件中删除白边距的方法。就像 Adob​​e 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();
}
4

2 回答 2

20

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

  1. 将 PDF 每页 2 面转换为每页 1 面(SuperUser.com)
  2. 将pdf页面从中间拆分的免费软件?(超级用户.com)
  3. 使用 Ghostscript 9.01 (StackOverflow.com)

第三个答案可能是让您说“我知道它不适用于每个 PDF 文件”的原因。它使用 pdfmark命令尝试设置/CropBoxPDF 页面对象。

前两个答案的方法很可能在第三个答案失败的情况下成功。此方法使用 PostScript 命令片段<</PageOffset [NNN MMM]>> setpagedevice来移动 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.5x10in (== 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

这会告诉你...

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

这表示:

  • 第 1 页72pt == 1in == 25,4mm在左边缘 ( )使用 57pt 的空白。
  • 第 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 页文档,那么这一切都更容易完成......

于 2012-05-02T17:25:54.210 回答
9

尝试pdfcrop。它需要ghostscript。

于 2012-05-04T15:36:58.763 回答