PDF - 去除白边距

14

我想知道如何从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个回答

21

我对PyPDF不是很熟悉,但我知道Ghostscript可以为你完成这件事。以下是一些类似问题的其他答案链接:

  1. 将每页2面的PDF转换为每页1面 (SuperUser.com)
  2. 分割pdf页面的免费软件? (SuperUser.com)
  3. 使用Ghostscript 9.01裁剪PDF (StackOverflow.com)

第三个答案可能让您说'我明白它无法与每个PDF文件一起使用'。它使用 pdfmark 命令尝试将/CropBox设置到PDF页面对象中。

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

如果您理解前两个答案背后的概念,您很容易就能够将那里使用的方法适应于裁剪PDF页面的所有4条边缘:

裁剪信纸大小PDF(8.5x11寸==612x792pt)每个边缘半英寸(==36pt)的示例命令(Windows命令):

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

在Linux或Mac上进行相同的操作,请使用以下命令:

生成的页面大小将为7.5x10in(== 540x720pt)。

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

这将告诉您:

  • ...第一页内容矩形的左下角坐标为[57 29],右上角坐标为[562 741]
  • ...第二页内容矩形的左下角坐标为[57 28],右上角坐标为[561 667]

这意味着:

  • 第一页左侧边缘使用了57pt的空白(72pt == 1in == 25,4mm)。
  • 第一页底部边缘使用了29pt的空白。
  • 第二页左侧边缘使用了57pt的空白。
  • 第二页底部边缘使用了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都是独特的页面尺寸,或者它们是单页文档,那么完成所有操作会更加容易...


2
@jacktrades:当然,如果你喜欢的话可以使用iText。请随意使用。但是,如果你想使用iText,你需要编写一个使用iText API的Java程序来完成它。而使用Ghostscript,你可以保持在脚本编程领域,这在这种情况下是我更喜欢的... - Kurt Pfeifle
@KurtPfeifle:我同意在所有情况下指定明确的分辨率可能是不可接受的。然而,我的(有限的)实验表明,在仅包含文本而没有图形的文件上使用“-r72”已经产生了巨大的影响。这可能是特定于我的ghostscript安装,但是没有“-r72”选项的情况下,时间差为13分钟,而使用该选项后只需18秒。 - Prakash K
@PrakashK:这似乎是一个有趣的文件。你介意分享一下(链接)吗? - Kurt Pfeifle
@KurtPfeifle:我用“pdfcrop”处理了另一个900多页的文件(带有一些图片)。与上一个文件相比,差别不是那么显著。如果没有“—resolution”选项,需要3.5分钟,使用该选项只需2分钟。 - Prakash K
1
@PrakashK:我刚刚检查了一下——bbox设备出于某种奇怪的原因使用默认分辨率为4000 dpi。我一直以为它会使用72 dpi。(我通过运行gs -o /dev/null -sDEVICE=bbox -c "currentpagedevice {exch ==only ( ) print ==} forall quit" | grep -i resolution来进行检查。另请参见“查询Ghostscript输出设备(如'pdfwrite'或'tiffg4')的默认选项/设置”)。 - Kurt Pfeifle
显示剩余15条评论

9
尝试使用pdfcrop。它需要ghostscript支持。

2
关于“大文件”问题,在这篇博客文章的评论中,他们建议使用pdfcrop --xetex --resolution 72 [other-options] input.pdf output.pdf来解决它。 - Andrea Lazzarotto
2
免费、快速、自动并且正确地识别边距,预装好的。正是我所需要的。 - fuenfundachtzig
它无法处理受密码保护的PDF文件。 - Venktaish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接