PDFのページを複数のページに切り刻みます[終了]


16

1つのPDFページに2つの「実際の」ページを含むPDFファイルがたくさんあります。これらを半分に切り分け、それぞれを別々のページに配置したいと思います。基本的に、pdfnup(またはpsnup)の正反対のことをするものが必要です。この偉業はどのように達成できますか?

プラットフォームはLinuxで、オープンソースが推奨されます。私はこれらの素晴らしい山を持っているので(GUIとは対照的に)スクリプト化できる何かをするのは良いことなので、それらのリストを与えてそれをかじってもらうことができます。

また、既存のスクリプトだけがオプションではありません。サードパーティのライブラリを使用して同様の方法でPDFを操作するサンプルコードがある場合は、おそらくそれをハッキングして目的の操作を実行できます。


回答:


22

Ghostscriptを使用してこれを解決できます。pdftkそれだけではできません(私の知る限り)。これを手動で行うためのコマンドライン手順を紹介します。ページサイズとページ番号のさまざまなパラメーターを使用して、これをプロシージャとして簡単にスクリプト化できます。しかし、あなたはそれを自分でできると言った;-)

Ghostscriptを使用してこれを解決する方法...

...そしてその楽しみのために、私は最近、「ダブルアップ」ページを備えた入力ファイルではなく、「トレブルアップ」を備えた入力ファイルでそれ行いました。この場合の答えはこちらで読むことができます

あなたのケースはさらにシンプルです。次のようなものがあるようです。

+------------+------------+   ^
|            |            |   |
|      1     |      2     |   |
|            |            | 595 pt
|            |            |   |
|            |            |   |
|            |            |   |
+------------+------------+   v
             ^
            fold
             v
+------------+------------+   ^
|            |            |   |
|      3     |      4     |   |
|            |            | 595 pt
|            |            |   |
|            |            |   |
|            |            |   |
+------------+------------+   v
<---------- 842 pt -------->

4ページのPDFを1つ作成します。各ページのサイズは421 pt x 595 ptです。

最初の一歩

最初に、各入力ページから左側のセクションを抽出しましょう。

gs \
    -o left-sections.pdf \
    -sDEVICE=pdfwrite \
    -g4210x5950 \
    -c "<</PageOffset [0 0]>> setpagedevice" \
    -f double-page-input.pdf

これらのパラメーターは何をしましたか?

まず、PDFで1インチ== 72ポイントであることを知ってください。それから残りは:

  • -o ...............:出力ファイルに名前を付けます。暗黙的にも使用し-dBATCH -dNOPAUSE -dSAFERます。
  • -sDEVICE=pdfwrite : 出力形式としてPDFが必要です。
  • -g................:出力メディアのサイズをピクセル単位で設定します。pdfwriteのデフォルトの解像度は720 dpiです。したがって、PageOffsetに一致するように10を掛けます。
  • -c "..............:Ghostscriptに、指定されたPostScriptコードスニペットをメイン入力ファイルの直前に処理するよう要求します(これはに従う必要があります-f)。
  • <</PageOffset ....:メディア上のページ画像のシフトを設定します。(もちろん、左ページの場合、シフトによる[0 0]影響はありません。)
  • -f ...............: この入力ファイルを処理します。

最後のコマンドはどの結果を達成しましたか?

これです:

Output file: left-sections.pdf, page 1
+------------+  ^
|            |  |
|     1      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

Output file: left-sections.pdf, page 2
+------------+  ^
|            |  |
|     3      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v
<-- 421 pt -->

第二段階

次に、適切なセクション:

gs \
    -o right-sections.pdf \
    -sDEVICE=pdfwrite \
    -g4210x5950 \
    -c "<</PageOffset [-421 0]>> setpagedevice" \
    -f double-page-input.pdf

表示領域を固定したままページを左にシフトしているため、負のオフセットに注意してください。

結果:

Output file: right-sections.pdf, page 1
+------------+  ^
|            |  |
|     2      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

Output file: right-sections.pdf, page 2
+------------+  ^
|            |  |
|     4      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v
<-- 421 pt -->

最後のステップ

次に、ページを1つのファイルに結合します。ghostscriptでも同様にできますが、pdftk代わりに使用します。このジョブの方が高速だからです。

pdftk \
  A=right-sections.pdf \
  B=left-sections.pdf \
  shuffle \
  output single-pages-output.pdf
  verbose

できた これが望ましい結果です。4つの異なるページ、サイズ421x595 pt。

結果:

+------------+ +------------+ +------------+ +------------+   ^
|            | |            | |            | |            |   |
|     1      | |     2      | |     3      | |     4      |   |
|            | |            | |            | |            |5595 pt
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
+------------+ +------------+ +------------+ +------------+   v
<-- 421 pt --> <-- 421 pt --> <-- 421 pt --> <-- 421 pt -->

@不明:投票してくれてありがとう!この理由を示すコメントを書いてください。
クルトファイフル

ASCIIアートの素​​晴らしい使用法と非常に明確な指示のために+1。私はCLI n00bだから、\ sは行をエスケープするので、読みやすくなりますか?
ジャーニーマンオタク

@mullhausen:タイプミスを修正してくれてありがとう(421-> -421)。;-)
カートファイフル

6

1つの入力ページ(ページのタイル張りまたはチョッピング)に対して複数のページを持つPDFを作成するために使用できるpdfposterツールがあります。これはposter、PostScriptファイルに対して同じことを行うツールに似ています。


pdfposterは、ポスターの組み立てを容易にするために、端で重複するコンテンツの印刷を処理しません。ただし、Perlスクリプトなので、追加するのはかなり簡単です。
マティアスユリックス

3

そのため、さらに多くの検索を行った後(「PDFカットページ」の方がはるかに優れた検索であると思われます)、PDF / PS変換unpnupを使用しposterpdftk必要なことを正確に実行するという小さなスクリプトが見つかりました。少し長い道のりですが、ページを吐き出す前にラスタライズしないので、私が見つけた他の方法(imagemagickを使用するなど)よりもはるかに優れています。

何らかの理由でmobilereadがなくなった場合に備えて、スクリプトのコア(GPLv2以降でHarald Hackenbergによってライセンスされて<hackenberggmx.at>います)は次のとおりです。

pdftk "$1" burst
for file in pg*.pdf;
do
    pdftops -eps $file
    poster -v -pA4 -mA5 -c0% `basename $file .pdf`.eps > `basename $file .pdf`.tps
    epstopdf `basename $file .pdf`.tps
done
pdftk pg*.pdf cat output ../`basename $1 .pdf`_unpnuped.pdf

1
人々が自分の質問に答えるとき、それを愛さなければなりません。あなたはGUIでそれを行うために必要な場合は、ページ・サイズがさえなかったか、さらに作物へのそれぞれの側を望んだ場合は特に、Brissをチェックアウト:briss.sourceforge.net
frabjous

すべての変換を行うことなく、PDFTKを使用して必要な処理を単独で実行できる必要があります。
CarlF

@CarlF:可能だと思いましたが、ページのコンテンツを操作するためのPDFTKマニュアルページには何も表示されません。私に何か指針がありますか?
ワンブル

@frabjous:自分の質問に答えることの何が問題になっていますか?
カートPfeifle

1
@womble:コンバージョンはPS / EPSを経由します。これは、品質の低下(埋め込みフォント、透明度など)につながるはずです。私の提案は、危険なPDF => EPS => PDFルートを回避し、より安全なPDF => PDF => PDF方法になります。
カートPfeifle

2

Kurt Pfeifleの答えは、私の同じような状況に非常に役立つことがわかりました。ソリューションの変更を他の人と共有できると思いました...

私も、各シートに2ページのスキャンされたPDFがありました。これは、最初にスキャンしたときに中綴じされた小冊子の11 x 8.5(インチ)スキャンであったため、PDFページ1 =裏表紙。PDFページ2 =ページ2および3など。これは画面上では正常に表示されますが、印刷してからステープルで留めて冊子のコピーを作成することはできません。

これを両面コピー機で印刷できるようにする必要がありました。つまり、「インポーズされた」PDFに戻し、印刷の準備を整えます。そこで、Kurtのソリューションを使用して、これを「ワンライナー」にして、再び正しいページ順序でハーフページに変換しました。これは、任意の高さと幅、および任意のページ数で機能します。私の場合、40ページの小冊子がありました(PDFで20ページをスキャンしました)。

HEIGHT=8.5 WIDTH=11 ORIG_FILE_PATH="original.pdf" \
count=$(set -xe; \
gs -o left.pdf -sDEVICE=pdfwrite \
-g$(perl -e "print(($WIDTH / 2) * 720)")x$(perl -e "print($HEIGHT * 720)") \
-c "<</PageOffset [0  0]>> setpagedevice" \
-f "$ORIG_FILE_PATH" >/dev/null; \
gs -o right.pdf -sDEVICE=pdfwrite \
-g$(perl -e "print(($WIDTH / 2) * 720)")x$(perl -e "print($HEIGHT * 720)") \
-c "<</PageOffset [-$(perl -e "print(($WIDTH / 2) * 72)")  0]>> setpagedevice" \
-f "$ORIG_FILE_PATH" | grep Page | wc -l ); \
echo '>>>>>' Re-ordering $count pages...; \
(set -xe; pdftk A=right.pdf B=left.pdf cat \
A1 `set +xe; for x in $(seq 2 $count); do echo B$x A$x; done` B1 \
output ordered.pdf); \
echo "Done. See ordered.pdf"

このコマンドの最初のいくつかのパラメーターを変更するだけで、HEIGHT、WIDTH、ORIG_FILE_PATHを指定できます。コマンドの残りの部分はさまざまなサイズを計算し、gsを2回呼び出してから、pdftkを呼び出します。スキャンのページをカウントし、正しいソート仕様を生成します(私が与えたシナリオの場合)。

実行内容に関する進捗を出力します。これは次のようになります。

+++ perl -e 'print((11 / 2) * 720)'
+++ perl -e 'print(8.5 * 720)'
++ gs -o left.pdf -sDEVICE=pdfwrite -g3960x6120 -c '<</PageOffset [0  0]>> setpagedevice' -f original.pdf
++ wc -l
++ grep Page
+++ perl -e 'print((11 / 2) * 720)'
+++ perl -e 'print(8.5 * 720)'
+++ perl -e 'print((11 / 2) * 72)'
++ gs -o right.pdf -sDEVICE=pdfwrite -g3960x6120 -c '<</PageOffset [-396  0]>> setpagedevice' -f original.pdf
>>>>> Re-ordering 20 pages...
++ set +xe
+ pdftk A=right.pdf B=left.pdf cat A1 B2 A2 B3 A3 B4 A4 B5 A5 B6 A6 B7 A7 B8 A8 B9 A9 B10 A10 B11 A11 B12 A12 B13 A13 B14 A14 B15 A15 B16 A16 B17 A17 B18 A18 B19 A19 B20 A20 B1 output ordered.pdf
Done. See ordered.pdf

次に、印刷された小冊子に必要なページの面付けを取得するには、ちょうど必要なサイズ(私の例では5.5 x 8.5)のカスタムページサイズでordered.pdfを「印刷」し、「小冊子作成」に送信します。 "ツール(私の場合、Christoph VogelbuschのCreate Booklet for Macを使用しました。 http:)。

結果のPDFは11 x 8.5の元のページサイズに戻り、1シートあたり2ページになりますが、順序は、両面印刷、短辺綴じ、およびボイラです。印刷して、コピーして折り、中綴じし、元のブックレットを分解することなく(または必然的に見ることなく)複製することができます。

これが誰かを助けることを願っています!

-c


1

上記のpiptasの回答に基づく:

Windowsでは、開始時に単一の表紙画像でレターサイズのPDFを分割するために、次のことがうまくいきました(2番目のステップで[-612 0]を使用すると、間違った方法でプッシュされるために正の値が空白ページを作成しました) )

gswin32c -o left-sections.pdf -sDEVICE=pdfwrite -dFirstPage=2 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

を使用すると、-dFirstPage=2gsが2ページで処理を開始するように指示されます。

gswin32c -o right-sections.pdf -sDEVICE=pdfwrite -dFirstPage=2 -g6120x7920 -c "<</PageOffset [-612 0]>> setpagedevice" -f input.pdf

これにより、right-sections.pdfが同じ方法で作成されます。そして今、カバー画像:

gswin32c -o cover.pdf -sDEVICE=pdfwrite -dLastPage=1 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

次に、手動ページ入力を使用してpdftkとマージしたくないので、新しいセクションで左右のセクションを別々のPDFに分割しました。

mkdir input_file
copy cover.pdf input_file\0000.pdf
pdftk left-sections.pdf burst output input_file\%04d_A.pdf
pdftk right-sections.pdf burst output input_file\%04d_B.pdf

次に、そのディレクトリ内のPDFをアルファベット順に(そして幸いなことに正しい順序で並べ替えられることを意味します!)結合し、ゴーストスクリプトで結果を再度実行して、「警告:世代番号が0..65535の範囲外であると仮定して、 0.」ghostscriptが「itext-paulo-155(itextpdf.sf.net-lawagie.com)」と呼ぶpdftkによって生成されたエラー-使用中にファイルサイズが半分に削減されることもありました。4.5MBのオリジナルでは、pdftkの結果は6.7MBで、gswin32cの再処理により3.2MBに削減されました。

pdftk input_file\*.pdf cat output input_temp.pdf
gswin32c -o final_output.pdf -sDEVICE=pdfwrite -f input_temp.pdf

これで完了です!input_fileフォルダー、cover.pdf、input_temp.pdf、right_sections.pdf、left_sections.pdfを自由に削除してください。;-)


1

左側のpdfをすべて1つのドキュメントに出力し、右側のpdfをすべて1つのドキュメントに出力する必要がある場合、Kurt Pfeifleの答えに基づいた次のスクリプトがトリックを実行します(任意の高さと幅):

$ cat split.sh
#!/bin/bash                                                                     

dims=$(pdfinfo "$1" | grep -i "page size:" | cut -d ":" -f2)                    
width=$(echo "$dims" | cut -d " " -f7)                                          
height=$(echo "$dims" | cut -d " " -f9)                                         
half_width=$(echo "$width * 0.5" | bc -l | cut -d "." -f1)                      
half_widthtt=$(echo "$width * 5" | bc -l | cut -d "." -f1)                      
heighttt=$(echo "$height * 10" | bc -l | cut -d "." -f1)                        

echo "pdf $1 has height $height and width $width"                               

gs -o "left-$1" -sDEVICE=pdfwrite -g"$half_widthtt"x"$heighttt" -c "<</PageOffset [0 0]>> setpagedevice" -f "$1"
gs -o "right-$1" -sDEVICE=pdfwrite -g"$half_widthtt"x"$heighttt" -c "<</PageOffset [-$half_width 0]>> setpagedevice" -f "$1"

それを次のように実行します:

$ ./split.sh thepdftosplit.pdf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.