Phi*_*ide 12 pdf image-manipulation
我有一些从原件扫描的电子书。它们的格式设置为单个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 - -
Run Code Online (Sandbox Code Playgroud)
第二个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%
Run Code Online (Sandbox Code Playgroud)
Chr*_*ill 14
这应该工作它需要pdftk
工具(和ghostscript
)。
第一步:拆分成单独的页面
pdftk clpdf.pdf burst
Run Code Online (Sandbox Code Playgroud)
这会生成文件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
Run Code Online (Sandbox Code Playgroud)
第三步:左右合并以生成newfile.pdf
包含单页的 .pdf。
ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
pdftk `cat fl` cat output newfile.pdf
Run Code Online (Sandbox Code Playgroud)
上面的示例假设所有页面的大小都相同。该doc_data.txt
文件包含每个拆分页面的大小。如果命令
grep PageMediaDimensions <doc_data.txt | sort | uniq | wc -l
不返回 1 则页面具有不同的维度,并且在第二步中需要一些额外的逻辑。
如果拆分不完全是 50:50 w2=$(( pw / 2 ))
,则需要比上面示例中使用的 更好的公式。
第二个示例展示了如何处理这种更一般的情况。
第一步:与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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
第四步:这与上一个更简单的示例中的合并步骤相同。
ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
pdftk `cat fl` cat output newfile.pdf
Run Code Online (Sandbox Code Playgroud)
您可以通过将 pdf 转换为 PostScript 来扩大您的工具选择,如下所示,然后使用pstops。我假设我们从显示两页的 A4 纵向页面开始,因为它们可能是从一本打开的书上扫描的,书脊水平穿过中间,如下所示:
显然,您可以更改下面解决方案中的值以适合您的具体情况。
pdf2ps
您可以使用(ghostscript 包的一部分)将此 pdf 转换为 PostScript 。然后,可以使用 psutils 包中的工具pstops
围绕左下角向右(顺时针)旋转页面,重新缩放并将结果向上移动,以便只有下半部分覆盖整个页面:
可以通过类似的旋转、缩放和平移从同一原始页面创建第二页面。结果可以转换回pdf。单个命令可以将每个页面绘制到 2 个新页面上:
pdf2ps myfile.pdf out.ps
pstops -p a4 '0R@1.2(1cm,29cm),0R@1.2(-16cm,29cm)' out.ps new.ps
ps2pdf new.ps new.pdf
Run Code Online (Sandbox Code Playgroud)
语法在手册页中有解释。这里我们有R
向右旋转,@1.2 缩放,(x,y) 移动结果。逗号 (,) 从每个原始页生成 2 页。
请注意,这将使生成的 pdf 大小加倍,因为每个页面都会完全绘制两次,即使您每次只看到一半。