【问题标题】:Crop PDF Content裁剪 PDF 内容
【发布时间】:2016-07-26 10:11:55
【问题描述】:

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

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

我在 postscript 中也遇到了问题 - 在 pdf->ps->pdf 转换期间出现透明度、字体光栅化和其他视觉故障的问题。

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

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

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

问题“Ghostscript removes content outside the crop box?”暗示ghostscript的pdfwrite模块,在生成输出pdf文件时,会根据crop box对内容进行光栅化和裁剪。所以我只需要通过 ghostscript 的 pdfwrite 模块来传输我的 pdf 文件。不幸的是,这不起作用。

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

所以:

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

如何访问它?

我认为此功能可能由 cup 的 pdftopdf 二进制文件提供。我调用外部二进制文件没有任何问题......但不知道如何使用pdftopdf

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

【问题讨论】:

    标签: pdf latex pdf-generation ghostscript pdfrw


    【解决方案1】:

    诀窍是使用 Form XObjects 将多个页面强加在单个页面中。表单 XObjects 可以引用整个 PDF 页面,并维护独立的剪辑。 PyPDF2 不支持 Form XObjects,因此合并会统一所有输入页面的流,以便它们共享输出页面的剪辑/媒体框。我已经成功地使用了 pdflatex 和 pdfrw (python) - 测试程序在下面内联。由于表单 XObjects 源自类似的 postscript 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:

    \documentclass{article}
    \usepackage{pdfpages}
    \usepackage[paperwidth=8.5in, paperheight=11in]{geometry}
    \usepackage[multidot]{grffile}
    \pagestyle{plain}
    
    \begin{document}
        \setlength\voffset{+0.0in}
        \setlength\hoffset{+0.0in}
    
        \includepdf[ noautoscale=true
                   , frame=false
                   , pages={1}
                   ]
                   {<file.pdf>}
    
        \eject \paperwidth=17in \pdfpagewidth=17in \paperheight=11in \pdfpageheight=11in 
    
        \includepdf[ nup=2x1
                   , noautoscale=true
                   , frame=false
                   , pages={2-,}
                   ]
                   {<file.pdf>}
    \end{document}
    

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

    #!/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 0.2 的一些特性:

    • 请注意,操作+=appendextend 没有为pdfrw.PageMerge 定义,即使它的行为类似于列表。此外,+ 的作用类似于 +=,因为它修改了左侧对象。

    【讨论】:

      【解决方案2】:

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

      被完全剪掉的对象不会保存到输出中。

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

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

      【讨论】:

      • 这如何应用于跨越页面/裁剪框边界的对象? ghostscript 可以在没有将页外内容覆盖到相邻页面上的情况下强加此类页面(2->1)吗?
      • CUPS 似乎不是修改或裁剪跨页/页外内容,而是为每个单独的项目添加掩码。我可以用 ghostscript 复制它吗?
      • 页面剪辑应该被保留(缩放、翻译等,视情况而定),这意味着跨越剪辑区域的对象将被保留,并根据需要进行剪辑。您可以使用 Ghostscript 复制“CUPS”的明显行为,但这样做是一项艰巨的任务,您必须广泛修改 pdfwrite 设备,这无疑是最复杂的设备Ghostscript(几个数量级)。由于原始页面剪辑无论如何都应该完成这项工作,我看不出会有什么收获。
      • 您能否展示一个使用 ghostscript 与页面剪辑拼版的示例?
      • 不,我手头没有例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 2011-08-13
      • 2013-06-09
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      相关资源
      最近更新 更多