如何使用命令列將每個 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

相關內容