我有一个扫描的pdf文件,已在一个虚拟页面(pdf文件中的页面)上扫描了两页。
分辨率良好。问题是我必须在阅读时进行缩放并从左向右拖动。
是否有一些命令(convert
,,pdftk
...)或脚本可以将此pdf文件转换为普通页面(书中的一页= pdf文件中的一页)?
pdfnup
从pdfjam
套件中通过命令行(而不是“打印到文件”)从命令行获得反向操作(连接多个页面)。
我有一个扫描的pdf文件,已在一个虚拟页面(pdf文件中的页面)上扫描了两页。
分辨率良好。问题是我必须在阅读时进行缩放并从左向右拖动。
是否有一些命令(convert
,,pdftk
...)或脚本可以将此pdf文件转换为普通页面(书中的一页= pdf文件中的一页)?
pdfnup
从pdfjam
套件中通过命令行(而不是“打印到文件”)从命令行获得反向操作(连接多个页面)。
Answers:
这是一个使用PyPdf库的小型Python脚本,可以很好地完成这项工作。将其保存在名为un2up
(或您喜欢的脚本)的脚本中,使其可执行(chmod +x un2up
),然后作为过滤器(un2up <2up.pdf >1up.pdf
)运行。
#!/usr/bin/env python
import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
input = PdfFileReader(sys.stdin)
output = PdfFileWriter()
for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
q = copy.copy(p)
(w, h) = p.mediaBox.upperRight
p.mediaBox.upperRight = (w/2, h)
q.mediaBox.upperLeft = (w/2, h)
output.addPage(p)
output.addPage(q)
output.write(sys.stdout)
忽略任何弃用警告;只有PyPdf维护者需要关心这些。
如果输入的方向不正常,则在截断页面时可能需要使用不同的坐标。请参阅为什么我的代码无法正确地将扫描的pdf中的每一页分开?
万一有用,这是我之前的答案,它结合使用了两种工具和一些手动干预:
这两个工具都是必需的,因为据我所知pdfpages不能在一个流中对同一页面应用两种不同的转换。在对的调用中pdftk
,将42替换为输入文档(2up.pdf
)中的页数。
pdfjam -o odd.pdf --trim '0cm 0cm 14.85cm 0cm' --scale 1.141 2up.pdf
pdfjam -o even.pdf --trim '14.85cm 0cm 0cm 0cm' --scale 1.141 2up.pdf
pdftk O=odd.pdf E=even.pdf cat $(i=1; while [ $i -le 42 ]; do echo O$i E$i; i=$(($i+1)); done) output all.pdf
如果您没有pdfjam 2.0,则只需安装带有pdfpages软件包的PDFLaTeX(在Ubuntu上:您需要texlive-latex-recommended ,也许(在Ubuntu上:texlive-fonts-recommended ),并使用以下驱动程序文件driver.tex
:
\batchmode
\documentclass{minimal}
\usepackage{pdfpages}
\begin{document}
\includepdfmerge[trim=0cm 0cm 14.85cm 0cm,scale=1.141]{2up.pdf,-}
\includepdfmerge[trim=14.85cm 0cm 0cm 0cm,scale=1.141]{2up.pdf,-}
\end{document}
然后运行以下命令,用输入文件中的页面数替换42(必须调用2up.pdf
):
pdflatex driver
pdftk driver.pdf cat $(i=1; pages=42; while [ $i -le $pages ]; do echo $i $(($pages+$i)); i=$(($i+1)); done) output 1up.pdf
pdfjam
命令。
q.mediaBox.lowerRight = (w, h/2)
由于我对python脚本(以及其他几个解决方案)有疑问,这只是一个补充:对我来说mutool
很棒。这是优雅的mupdf
阅读器附带的一个简单且小的附件。因此,您可以尝试:
mutool poster -y 2 input.pdf output.pdf
对于水平分割,请替换y
为x
。当然,您可以将两者结合起来以获得更复杂的解决方案。
真的很高兴找到这个(多年使用mupdf多年:)
mutool
从1.4版开始随附mupdf:http://www.mupdf.com/news
mupdf
并mutool
从源头:wget http://www.mupdf.com/downloads/mupdf-1.8-source.tar.gz
tar -xvf mupdf-1.8-source.tar.gz
cd mupdf-1.8-source
sudo make prefix=/usr/local install
或转到下载页面以找到较新的版本。
mutool
为此。另外,请注意-y
,在大多数情况下,我认为您想要的是-x
。
Imagemagick可以一步完成:
$ convert in.pdf -crop 50%x0 +repage out.pdf
-density 400
参数`,它将具有更好的质量。
ImageMagick的Convert命令可以帮助您分两部分裁剪文件。参见http://www.imagemagick.org/使用情况/ crop /
如果我是你,我会写一个像这样的(shell)脚本:
对于每一页,裁剪前半部分并将其放入名为$ {PageNumber} A的文件中
裁剪后半部分,并将其放入名为$ {PageNumber} B的文件中。
您将获得1A.pdf,1B.pdf,2A.pdf,2B.pdf等。
基于Gilles的回答以及我写的如何查找PDF页面数
#!/bin/bash
pdforiginal=$1
pdfood=$pdforiginal.odd.pdf
pdfeven=$pdforiginal.even.pdf
pdfout=output_$1
margin=${2:-0}
scale=${3:-1}
pages=$(pdftk $pdforiginal dump_data | grep NumberOfPages | awk '{print $2}')
pagesize=$(pdfinfo $pdforiginal | grep "Page size" | awk '{print $5}')
margin=$(echo $pagesize/2-$margin | bc -l)
pdfjam -o $pdfood --trim "0cm 0cm ${margin}pt 0cm" --scale $scale $pdforiginal
pdfjam -o $pdfeven --trim "${margin}pt 0cm 0cm 0cm" --scale $scale $pdforiginal
pdftk O=$pdfood E=$pdfeven cat $(i=1; while [ $i -le $pages ]; do echo O$i E$i; i=$(($i+1)); done) output $pdfout
rm $pdfood $pdfeven
这样我就可以跑步
./split.sh my.pdf 50 1.2
其中50表示调整边距,1.2表示比例。
这是Gilles发布的PyPDF代码的变体。无论页面方向是什么,此功能都将起作用:
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()
最好的解决方案是mutool,请参见上文:
sudo apt install mupdf-tools pdftk
拆分:
mutool poster -y 2 input.pdf output.pdf
但是然后您需要向左旋转页面:
pdftk output.pdf cat 1-endleft output rotated.pdf
ora 解决方案对我不起作用。主要问题是x5和x6计算。这里必须考虑偏移量,即,如果lowerLeft不为(0,0)
所以这是另一个变体,使用PyPDF2和python进行了其他修改:
import copy
import math
import PyPDF2
import sys
import io
def split_pages(src, dst):
src_f = io.open(src, 'r+b')
dst_f = io.open(dst, 'w+b')
input = PyPDF2.PdfFileReader(src_f)
output = PyPDF2.PdfFileWriter()
for i in range(input.getNumPages()):
p = input.getPage(i)
q = copy.copy(p)
q.mediaBox = copy.copy(p.mediaBox)
x1, x2 = p.cropBox.lowerLeft
x3, x4 = p.cropBox.upperRight
x1, x2 = math.floor(x1), math.floor(x2)
x3, x4 = math.floor(x3), math.floor(x4)
x5 = math.floor((x3-x1) / 2 + x1)
x6 = math.floor((x4-x2) / 2 + x2)
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.lowerLeft = (x1, x6)
p.mediaBox.upperRight = (x3, x4)
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()
if __name__ == "__main__":
if ( len(sys.argv) != 3 ):
print ('Usage: python3 double2single.py input.pdf output.pdf')
sys.exit(1)
split_pages(sys.argv[1], sys.argv[2])