1

我想将 2x2 pdf 文档拆分为其原始页面。每个页面由四个逻辑页面组成,这些逻辑页面的排列方式如例所示。

我正在尝试使用pythonpypdf

import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader

def ifel(condition, trueVal, falseVal):
    if condition:
        return trueVal
    else:
        return falseVal

input  = PdfFileReader(file(sys.argv[1], "rb"))
output = PdfFileWriter()

for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
    (w, h) = p.mediaBox.upperRight

    for j in range(0,4):
        t = copy.copy(p)        
        t.mediaBox.lowerLeft  = (ifel(j%2==1, w/2, 0), ifel(j<2, h/2, 0))
        t.mediaBox.upperRight = (ifel(j%2==0, w/2, w), ifel(j>1, h/2, h))
        output.addPage(t)

output.write(file("out.pdf", "wb"))

不幸的是,这个脚本没有按预期工作,因为它每四个逻辑页输出四次。由于我之前没有用python写过任何东西,我认为这是一个非常基本的问题,大概是由于复制操作。我真的很感激任何帮助。


编辑:嗯,我做了一些实验。我手动插入了页面宽度和高度,如下所示:

import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader

def ifel(condition, trueVal, falseVal):
    if condition:
        return trueVal
    else:
        return falseVal

input  = PdfFileReader(file(sys.argv[1], "rb"))
output = PdfFileWriter()

for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
    (w, h) = p.mediaBox.upperRight

    for j in range(0,4):
        t = copy.copy(p)        
        t.mediaBox.lowerLeft  = (ifel(j%2==1, 841/2, 0),   ifel(j<2, 595/2, 0))
        t.mediaBox.upperRight = (ifel(j%2==0, 841/2, 841), ifel(j>1, 595/2, 595))
        output.addPage(t)

output.write(file("out.pdf", "wb"))

此代码导致与我原来的相同的错误结果,如果我现在注释掉该行(w, h) = p.mediaBox.upperRight,一切正常!我找不到任何理由。元组(w, h)甚至不再使用,那么删除它的定义如何改变任何东西呢?

4

1 回答 1

0

我怀疑问题在于 mediaBox 只是一个变量的魔术访问器,在 p 和所有副本 t 之间共享。因此,分配 tot.mediaBox将导致 mediaBox 在所有四个副本中具有相同的坐标。

mediaBox 字段后面的变量是在第一次访问 mediaBox 时延迟创建的,因此如果您注释掉该行(w, h) = p.mediaBox.upperRight,则会为每个 t 单独创建 mediaBox 变量。

自动确定页面尺寸的两种可能解决方案:

  1. 制作副本后获取尺寸:

    for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
    
        for j in range(0,4):
            t = copy.copy(p)       
            (w, h) = t.mediaBox.upperRight
            t.mediaBox.lowerLeft  = (ifel(j%2==1, w/2, 0),   ifel(j<2, h/2, 0))
            t.mediaBox.upperRight = (ifel(j%2==0, w/2, w), ifel(j>1, h/2, h))
            output.addPage(t)  
    
  2. 实例化新的 RectangleObjects 以用于 mediaBox 变量

    for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
        (w, h) = p.mediaBox.upperRight
    
        for j in range(0,4):
            t = copy.copy(p)        
            t.mediaBox.lowerLeft  = pyPdf.generic.RectangleObject(
                                        ifel(j%2==1, w/2, 0),   
                                        ifel(j<2, h/2, 0),
                                        ifel(j%2==0, w/2, w), 
                                        ifel(j>1, h/2, h))
            output.addPage(t)
    

使用copy.deepcopy()会导致大型复杂 PDF 的内存问题,

于 2013-08-14T10:12:58.747 回答