裁剪PDF内容

时间:2016-04-06 07:05:54

标签: pdf latex pdf-generation ghostscript pdfrw

我有一个我想强加的pdf。它有8.5x11"页面,媒体框和裁剪框。我希望pdf有17x11"页面,通过合并相邻的页面。不幸的是,大多数页面都有完全在外面或跨越裁剪框的内容。因为每个页面只能有一个流和裁剪框,所以当强加时,重叠的内容变得可见。这很糟糕。

我不想光栅化我的PDF格式,因为这样可以提前修复DPI。所以我不会考虑将页面导出为图像,附加图像(imagemagick),然后将这些配对图像嵌入到新的pdf中。

我还在后记中遇到了问题 - 在pdf-> ps-> pdf转换过程中出现了透明度,字体光栅化和其他视觉故障等问题。

答案应该是可编写脚本的。

到目前为止,我已尝试过:

  • podofo拼版脚本(lua)
  • PyPDF2(python)
  • 的ghostscript
  • 胶乳

问题" Ghostscript removes content outside the crop box?"建议ghostscript的pdfwrite模块在生成输出pdf文件时,会根据裁剪框栅格化和裁剪内容。所以我只需要通过ghostscript的pdfwrite模块来管理我的pdf。不幸的是,这不起作用。

当我尝试通过evince将pdf打印到另一个pdf时,我正要放弃。它完美地运作 - 文本和裁剪框内的矢量元素不会被栅格化,并且裁剪框外的元素将被删除(我还没有测试跨越元素)。质量高分辨率(页面大小)和外观相同。事实上,除了元数据之外,一切似乎都是一样的。

所以:

  • 问题是可能的
  • 答案已经存在

我如何访问它?

我认为这个功能可能是由cup pdftopdf二进制文件提供的。我在调用外部二进制文件时没有任何问题....但无法弄清楚如何使用pdftopdf

编辑: Link to test pdf。它包含栅格,矢量和文本项目 - 一些部分透明项目部分遮挡 - 跨越以及邻接相邻页面。再次,通过杯子打印此PDF似乎裁剪裁剪框外的所有内容。但是,在inkscape中打开过滤后的pdf会显示页外项目是单独屏蔽的,而不是裁剪的 - 除了文本,它被裁剪。

2 个答案:

答案 0 :(得分:1)

诀窍是使用Form XObjects在一个页面中强加多个页面。表单XObjects可以引用整个PDF 页面,并维护独立的剪辑。 PyPDF2不支持Form XObjects,因此合并将统一所有输入页面的流,使它们共享输出页面的剪辑/媒体框。我已成功使用pdflatex和pdfrw(python) - 测试程序在下面内联。由于Form XObjects是从类似的postscript level 2特性派生的,正如KenS所建议的那样,应该可以使用“页面剪辑”在ghostscript中实现相同的目标。事实上he shared a ghostscript 2x1 imposition script in another answer,但它看起来非常复杂。结合poppler的 pdftops 的字体光栅化问题(即使兼容级别> 1.4),我已经放弃了ghostscript方法。

How to stitch two PDF pages together as one big page?派生的Latex脚本。需要pdflatex:

#!/usr/bin/env python3

# Copyright:
#   Yclept Nemo
#       2016
# License:
#   GPLv3

import itertools
import argparse
import pdfrw

# from itertool recipes in the python documentation
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

def pagemerge(page, *pages):
    merged = pdfrw.PageMerge() + page
    for page in reversed(list(itertools.takewhile(lambda i: i is not None, reversed(pages)))):
        merged = merged + page
        merged[-1].x = merged[-2].x + merged[-2].w
    return merged.render()

parser = argparse.ArgumentParser(description='Impose PDF files using Form XOBjects')

parser.add_argument\
    ( "source"
    , help="PDF, source path"
    , type=pdfrw.PdfReader
    )
parser.add_argument\
    ( "-s", "--spacer"
    , help="PDF, spacer path"
    , type=lambda fp: next(iter(pdfrw.PdfReader(fp).pages), None)
    )
parser.add_argument\
    ( "target"
    , help="PDF, target path"
    )

args = parser.parse_args()

pages = args.source.pages[:1]

for pair in grouper(args.source.pages[1:], 2):
    assert pair[0] is not None
    pages.append(pagemerge(pair[0], args.spacer, pair[1]))

# include metadata in target
target = pdfrw.PdfWriter()
target.addpages(pages)
target.trailer.Info = args.source.Info
target.write(args.target)

pdfrw(python脚本)派生自pdfrw:examples:booklet。需要pdfrw> = 0.2:

+=

pdfrw 0.2的一些特质:

  • 请注意,pdfrw.PageMerge没有定义操作appendextend+,即使它的行为类似于列表。此外,+=的作用类似于Button b1 = makeButton("Go to s2", s2); Button b2 = makeButton("Go to s1", s1); s1 = new Scene(b1); s2 = new Scene(b2); ,因为它会修改左侧对象。

答案 1 :(得分:0)

Ghostscript和pdfwrite设备通常不会光栅化输入PDF文件的内容(需要注意的是透明输入和输出为< PDF 1.4)。

完全剪掉的对象不会保留在输出中。

所以简短的回答是,使用Ghostscript和pdfwrite设备应该完全可行,其优点是可以在单个操作中强制执行页面。我确实有一个关于在类似情况下进行裁剪的开放式错误报告(反向拼版),但尚未有时间解决它。

请注意,Ghostscript通常使用 MediaBox 作为剪辑区域,如果要使用CropBox,则需要将-dUseCropBox添加到命令行。