【问题标题】:Split each PDF page in two?将每个 PDF 页面一分为二?
【发布时间】:2012-10-31 23:42:12
【问题描述】:

我有大量的 PDF 文件,每页有两张幻灯片(用于打印)。

格式为 A4 页面,每页有两张幻灯片,如下所示:

-----------
| slide 1 |
-----------
| slide 2 |
-----------

如何生成每页一张幻灯片的新 PDF 文件?

乐于使用 GUI、CLI、脚本甚至是与一种语言的 PDF 库的接口;但我确实需要幻灯片上的文本仍然可以选择。

【问题讨论】:

标签: pdf layout pdf-generation split


【解决方案1】:

PDF Scissors 允许我批量拆分(裁剪)PDF 中的所有页面。

【讨论】:

  • 有前途,但需要 Java :(
  • @TobiasKienzler 我修复了死链接:)
【解决方案2】:

mutool 出色地为此工作。下面的示例将input.pdf 的每一页分成 3 个水平部分和 8 个垂直部分(因此为每 1 个输入创建 24 页输出):

mutool poster -x 3 -y 8 input.pdf output.pdf

要安装 mutool,只需安装 mupdf,它可能与大多数 GNU/Linux 发行版一起打包。

(归功于marttt。)

在 ubuntu 等基于 debian 的 linux 系统上,您可以使用安装它

sudo apt install mupdf
sudo apt install mupdf-tools

【讨论】:

  • mutool 是一个非常强大的小程序。我建议查看它的手册页 (manpages.ubuntu.com/manpages/trusty/man1/mutool.1.html)。
  • 当我尝试使用这个命令时(在我的例子中是 mutool poster -y 2 input.pdf output.pdf),结果 output.pdf 的页面排序不正确。有没有什么办法解决这一问题?我在手册页中找不到它
  • @kaslusimoes 我猜你的输入文件方向与mutool 的期望不一致,在这种情况下你可以使用例如pdf180(来自pdfjam)在输入mutool 之前输入文件。另一方面,如果您的输入文件排序更复杂,您可以手动使用 mutool clean input.pdf output.pdf 2,1,3,4,6,5 重新排序页面,其中 2,1,3,4,6,5 是您想要的新排序。
【解决方案3】:

Briss 是“一个用于裁剪 PDF 文件的简单跨平台(Linux、Windows、Mac OSX)应用程序。简单的用户界面让您可以通过在视觉重叠的页面上放置一个矩形来准确定义裁剪区域。”它是开源的 (GPL)。

对我来说效果很好。 GUI 很小,但很实用。也可以在命令行中使用。

【讨论】:

  • 他们不得不继续称它为 Bris,不是吗>.<! - 干杯,我会检查一下:)
  • 爱你,成功了!我不得不将我的页面分成 4 个页面,这样就成功了!
  • 使用这个!像魅力一样工作!
【解决方案4】:

您可以使用名为 PyPDF 的 Python 库。无论页面方向如何,此功能都会拆分双页:

import copy
import math
import pyPdf

def split_pages(src, dst):
    src_f = file(src, 'r+b')
    dst_f = file(dst, 'w+b')

    input = pyPdf.PdfFileReader(src_f)
    output = pyPdf.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i)
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.mediaBox.lowerLeft
        x3, x4 = p.mediaBox.upperRight

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)
        x5, x6 = math.floor(x3/2), math.floor(x4/2)

        if x3 > x4:
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical
            p.mediaBox.upperRight = (x3, x4)
            p.mediaBox.lowerLeft = (x1, x6)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()

【讨论】:

  • 知道为什么这会用 python 2.7 和 pypdf 1.13 生成一个空文件吗?谢谢!
  • 这里为什么需要math.floor()
【解决方案5】:

感谢 Matt Gumbley 的 Python 脚本。我已经修改了 Python 脚本,使其现在也适用于包含纵向和横向页面以及裁剪页面的 PDF:

# -*- coding: utf-8 -*-
"""
Created on Thu Feb 26 08:49:39 2015

@author: Matt Gumbley  (stackoverflow)
changed by Hanspeter Schmid to deal with already cropped pages
"""

import copy
import math
from PyPDF2 import PdfFileReader, PdfFileWriter

def split_pages2(src, dst):
    src_f = file(src, 'r+b')
    dst_f = file(dst, 'w+b')

    input = PdfFileReader(src_f)
    output = PdfFileWriter()

    for i in range(input.getNumPages()):
        # make two copies of the input page
        pp = input.getPage(i)
        p = copy.copy(pp)
        q = copy.copy(pp)

        # the new media boxes are the previous crop boxes
        p.mediaBox = copy.copy(p.cropBox)
        q.mediaBox = copy.copy(p.cropBox)

        x1, x2 = p.mediaBox.lowerLeft
        x3, x4 = p.mediaBox.upperRight

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)
        x5, x6 = x1+math.floor((x3-x1)/2), x2+math.floor((x4-x2)/2)

        if (x3-x1) > (x4-x2):
            # horizontal
            q.mediaBox.upperRight = (x5, x4)
            q.mediaBox.lowerLeft = (x1, x2)

            p.mediaBox.upperRight = (x3, x4)
            p.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical
            p.mediaBox.upperRight = (x3, x4)
            p.mediaBox.lowerLeft = (x1, x6)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)


        p.artBox = p.mediaBox
        p.bleedBox = p.mediaBox
        p.cropBox = p.mediaBox

        q.artBox = q.mediaBox
        q.bleedBox = q.mediaBox
        q.cropBox = q.mediaBox

        output.addPage(q)
        output.addPage(p)


    output.write(dst_f)
    src_f.close()
    dst_f.close()

【讨论】:

    【解决方案6】:

    这是我使用pdfrw 的方法:

    import sys, os, pdfrw
    writer = pdfrw.PdfWriter()
    for page in pdfrw.PdfReader('input.pdf').pages:
        for y in [0, 0.5]:
            newpage = pdfrw.PageMerge()    
            newpage.add(page, viewrect=(0, y, 1, 0.5))
            writer.addpages([newpage.render()])
    writer.write('output.pdf')
    

    短而有效!

    如果您希望它旋转(例如:输入 A4 纵向,输出 2 个 A5 纵向而不是横向):

    import sys, os, pdfrw
    writer = pdfrw.PdfWriter()
    for page in pdfrw.PdfReader('input.pdf').pages:
        for y in [0, 0.5]:
            newpage = pdfrw.PageMerge()    
            newpage.add(page, viewrect=(0, y, 1, 0.5))
            p = newpage.render()
            p.Rotate = 270
            writer.addpages([p])
    writer.write('output.pdf')
    

    【讨论】:

      【解决方案7】:

      试试BRISS

      它允许您将每个页面拆分为任意数量的子页面 使用 GUI 定义区域。它将所有相似的页面分组 为您,因此您可以为该组定义一次区域。

      它是跨平台、免费和开源的。

      (从https://superuser.com/a/235327/35237复制粘贴)

      【讨论】:

        【解决方案8】:

        如果您可以使用 Java 或 .Net 库,您可以使用 iText / iTextSharp。

        可以在免费提供的chapter 6TilingHero.java/TilingHero.cs 中找到 iText in Action,第 2 版一书中平铺现有文档的示例。

        【讨论】:

          【解决方案9】:

          感谢 moraes 的回答。就我而言,生成的 PDF 在 Adob​​e Reader 和 Mac 预览中看起来不错,但在 iOS 上查看时似乎根本没有分成单独的页面。我使用了 Python 2.7.8 和 PyPDF 2,并将脚本修改如下,效果很好。 (并重新排列页面左/右,而不是右/左)。

          import copy
          import math
          from PyPDF2 import PdfFileReader, PdfFileWriter
          
          def split_pages(src, dst):
              src_f = file(src, 'r+b')
              dst_f = file(dst, 'w+b')
          
              input = PdfFileReader(src_f)
              output = PdfFileWriter()
          
              for i in range(input.getNumPages()):
                  p = input.getPage(i)
                  q = copy.copy(p)
                  q.mediaBox = copy.copy(p.mediaBox)
          
                  x1, x2 = p.mediaBox.lowerLeft
                  x3, x4 = p.mediaBox.upperRight
          
                  x1, x2 = math.floor(x1), math.floor(x2)
                  x3, x4 = math.floor(x3), math.floor(x4)
                  x5, x6 = math.floor(x3/2), math.floor(x4/2)
          
                  if x3 > x4:
                      # horizontal
                      p.mediaBox.upperRight = (x5, x4)
                      p.mediaBox.lowerLeft = (x1, x2)
          
                      q.mediaBox.upperRight = (x3, x4)
                      q.mediaBox.lowerLeft = (x5, x2)
                  else:
                      # vertical
                      p.mediaBox.upperRight = (x3, x4)
                      p.mediaBox.lowerLeft = (x1, x6)
          
                      q.mediaBox.upperRight = (x3, x6)
                      q.mediaBox.lowerLeft = (x1, x2)
          
          
                  p.artBox = p.mediaBox
                  p.bleedBox = p.mediaBox
                  p.cropBox = p.mediaBox
          
                  q.artBox = q.mediaBox
                  q.bleedBox = q.mediaBox
                  q.cropBox = q.mediaBox
          
                  output.addPage(q)
                  output.addPage(p)
          
              output.write(dst_f)
              src_f.close()
              dst_f.close()
          

          【讨论】:

          • 知道为什么这会用 python 2.7 和 pypdf 1.13 生成一个空文件吗?谢谢!
          • 这里为什么需要math.floor()
          • 创建页面的插入顺序不匹配。应该是output.addPage(p),然后是output.addPage(q)`
          【解决方案10】:

          使用mupdf-1.8-windows-x64,在win10 CMD中,你需要在水平参数(-x)之前有'poster'(后跟空格且不带引号)。 例如对于 PDF 的双页扫描:

          mutool poster -x 2 -y 1 C:\Users\alfie\Documents\SNM\The_Ultimate_Medicine.pdf C:\Users\alfie\Documents\ebooks\The_Ultimate_Medicine.pdf

          多么棒的工具啊!谢谢无限!.. (输出文件 ~9MB 仅比原始文件大 52KB!)

          【讨论】:

            猜你喜欢
            • 2011-05-01
            • 2016-03-23
            • 1970-01-01
            • 1970-01-01
            • 2013-07-20
            • 1970-01-01
            • 1970-01-01
            • 2021-12-08
            • 2018-10-09
            相关资源
            最近更新 更多