如何使用命令行将每个 PDF 页面拆分为两页?

如何使用命令行将每个 PDF 页面拆分为两页?

我有几本从原件扫描而来的电子书。它们被格式化为单个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 

更一般的情况:

  1. 上面的示例假设所有页面的大小相同。该doc_data.txt文件包含每个拆分页面的大小。如果命令

    grep PageMediaDimensions <doc_data.txt | sort | uniq | wc -l

    不返回 1,则页面具有不同的尺寸,并且需要一些额外的逻辑第二步

  2. 如果分割不完全是 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

您特别要求命令行解决方案 - 可能是因为您不想坐下来选择每个页面。

但如果可以接受每本书都打开,那就pdfarranger行了。

它不会使 PDF 文件的大小增加一倍。

分裂前 分裂后

答案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

相关内容