我有几本从原件扫描而来的电子书。它们被格式化为单个PDF页面包含两个实际页面: 左边一个,右边一个。
我想以编程方式将每个 PDF 页面分成两部分,因此 PDF 第 1 页的左侧 50% 成为第 1 页,右侧成为第 2 页,对于所有页面,依此类推。
有谁知道可以帮助解决此问题的命令行实用程序或脚本?
输出来自pdfimages -list -f 1 -l 1 file.pdf
:
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 1921 1561 rgb 3 8 jpeg no 643 0 200 200 200K 2.3%
1 1 stencil 1 1 - 1 1 image no [inline] 0.692 2 - -
1 2 stencil 1 1 - 1 1 image no [inline] 0.722 0.650 - -
1 3 stencil 1 1 - 1 1 image no [inline] 3 3 - -
第二个PDF:
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 456 625 gray 1 8 jpx yes 251 0 72 72 11.7K 4.2%
答案1
这应该可以工作,需要pdftk
工具(和ghostscript
)。
一个简单的案例:
步骤1:分成单独的页面
pdftk clpdf.pdf burst
这会生成文件pg_0001.pdf, pg_0002.pdf, ... pg_NNNN.pdf
,每一页一个。它还生成doc_data.txt
包含页面尺寸的内容。
第二步:创建左半页和右半页
pw=`cat doc_data.txt | grep PageMediaDimensions | head -1 | awk '{print $2}'`
ph=`cat doc_data.txt | grep PageMediaDimensions | head -1 | awk '{print $3}'`
w2=$(( pw / 2 ))
w2px=$(( w2*10 ))
hpx=$(( ph*10 ))
for f in pg_[0-9]*.pdf ; do
lf=left_$f
rf=right_$f
gs -o ${lf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [0 0]>> setpagedevice" -f ${f}
gs -o ${rf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [-${w2} 0]>> setpagedevice" -f ${f}
done
第三步:左右合并以生成newfile.pdf
包含单页的 .pdf。
ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
pdftk `cat fl` cat output newfile.pdf
更一般的情况:
上面的示例假设所有页面的大小相同。该
doc_data.txt
文件包含每个拆分页面的大小。如果命令grep PageMediaDimensions <doc_data.txt | sort | uniq | wc -l
不返回 1,则页面具有不同的尺寸,并且需要一些额外的逻辑第二步。
如果分割不完全是 50:50,则
w2=$(( pw / 2 ))
需要一个比上例中使用的 更好的公式。
第二个示例展示了如何处理这种更一般的情况。
步骤1:pdftk
与之前一样拆分
第二步:现在创建三个文件,其中包含每个页面的宽度和高度以及左侧页面将使用的分割部分的默认值。
grep PageMediaDimensions <doc_data.txt | awk '{print $2}' > pws.txt
grep PageMediaDimensions <doc_data.txt | awk '{print $3}' > phs.txt
grep PageMediaDimensions <doc_data.txt | awk '{print "0.5"}' > lfrac.txt
lfrac.txt
如果有关于在何处分割不同页面的信息,则可以手动编辑该文件。
第三步:现在,使用不同的页面大小和(如果已编辑)不同的小数位置进行拆分,创建左拆分页和右拆分页。
#!/bin/bash
exec 3<pws.txt
exec 4<phs.txt
exec 5<lfrac.txt
for f in pg_[0-9]*.pdf ; do
read <&3 pwloc
read <&4 phloc
read <&5 lfr
wl=`echo "($lfr)"'*'"$pwloc" | bc -l`;wl=`printf "%0.f" $wl`
wr=$(( pwloc - wl ))
lf=left_$f
rf=right_$f
hpx=$(( phloc*10 ))
w2px=$(( wl*10 ))
gs -o ${lf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [0 0]>> setpagedevice" -f ${f}
w2px=$(( wr*10 ))
gs -o ${rf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [-${wl} 0]>> setpagedevice" -f ${f}
done
第四步:这与前面更简单的示例中的合并步骤相同。
ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
pdftk `cat fl` cat output newfile.pdf
答案2
您可以通过将 pdf 转换为 PostScript 来扩大您的工具选择,如下所示,然后使用停止时间。我假设我们从显示两页的 A4 纵向页面开始,因为它们可能是从一本打开的书上扫描的,书脊水平穿过中间,如下所示:
显然,您可以更改下面解决方案中的值以适合您的具体情况。
pdf2ps
您可以使用(ghostscript 包的一部分)将此 pdf 转换为 PostScript 。然后,可以使用 psutils 包中的工具pstops
围绕左下角向右(顺时针)旋转页面,重新缩放并将结果向上移动,以便只有下半部分覆盖整个页面:
可以通过类似的旋转、缩放和平移从同一原始页面创建第二页面。结果可以转换回pdf。单个命令可以将每个页面绘制到 2 个新页面上:
pdf2ps myfile.pdf out.ps
pstops -p a4 '[email protected](1cm,29cm),[email protected](-16cm,29cm)' out.ps new.ps
ps2pdf new.ps new.pdf
语法在手册页中有解释。这里我们有R
向右旋转,@1.2 缩放,(x,y) 移动结果。逗号 (,) 从每个原始页生成 2 页。
请注意,这将使生成的 pdf 大小加倍,因为每个页面都会完全绘制两次,即使您每次只看到一半。
答案3
答案4
您可能想看看imagemagick
:
$ convert -resize 1000x1000 /links/www/Salix/pdf/index.pdf a.jpg
$ convert -crop 500x1000+0+0 a.jpg b.jpg
$ convert -crop 500x1000+500+0 a.jpg c.jpg
$ convert c.jpg c.pdf
$ convert b.jpg b.pdf