我想将2x2 pdf文档拆分为原始页面。每个页面由四个逻辑页面组成,这些页面的排列方式与this示例相似。
我正在尝试使用python
和pypdf
:
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)
甚至不再使用了,那么如何删除它的定义会改变什么呢?
答案 0 :(得分:0)
我怀疑问题在于mediaBox只是一个变量的魔术存取器,它在p和所有副本t之间共享。因此,t.mediaBox
的赋值将导致mediaBox在所有四个副本中具有相同的坐标。
mediaBox字段后面的变量是在第一次访问mediaBox时懒洋洋地创建的,所以如果你注释掉行(w, h) = p.mediaBox.upperRight
,将为每个t单独创建mediaBox变量。
自动确定页面尺寸的两种可能解决方案:
制作副本后获取尺寸:
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)
实例化用于mediaBox变量的新鲜RectangleObject
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的内存问题