web-dev-qa-db-ja.com

PDFのページを複数のページに切り刻む

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

プラットフォームはLinuxであり、オープンソースが推奨されます。 (GUIではなく)スクリプト化できる何かを実行するためにこれらの山がたくさんあるので、それらのリストを提供して、それをかみ砕くことができます。

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

16
womble

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

Ghostscriptの助けを借りてこれを解決する方法...

...そしてその面白さのために、私は最近、「ダブルアップ」ページを特徴とする入力ファイルでしないを行いましたが、 「トレブルアップ」。この場合の答えは here です。

あなたのケースはさらに簡単です。あなたはこれに似たものを持っているようです:

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

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

最初の一歩

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

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

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

まず、in PDF1インチ== 72ポイントであることを知ってください。残りは次のとおりです。

  • -o ...............:出力ファイルに名前を付けます。暗黙的に-dBATCH -dNOPAUSE -dSAFERも使用します。
  • -sDEVICE=pdfwrite :出力形式としてPDF)が必要です。
  • -g................:は出力メディアサイズをピクセル単位で設定します。 pdfwriteのデフォルトの解像度は720 dpiです。したがって、PageOffsetに一致させるには、10を掛けます。
  • -c "..............:は、メイン入力ファイルの直前に指定されたPostScriptコードスニペットを処理するようにGhostscriptに要求します(これは-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

完了。これが望ましい結果です。サイズ421x595ポイントの4つの異なるページ。

結果:

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

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

7
Philipp Wendler

したがって、さらに多くの検索を行った後(「PDFカットページ」の方がはるかに優れた検索のようです)、unpnupを使用する poster という小さなスクリプトを見つけました。 、PDF/PS変換、およびpdftkで必要な処理を正確に実行できます。それは少し長い道のりですが、私が見つけた他の方法(imagemagickを使用するなど)よりもはるかに優れています。

Mobilereadが何らかの理由でなくなった場合に備えて、スクリプトのコア(GPLv2以降でHaraldHackenbergによってライセンス供与されています<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
3
womble

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

私もスキャンしたPDF各シートに2ページありました。最初にスキャンしたときにホチキス止めされたままになっている中とじの小冊子の11x 8.5(インチ)スキャンでした。 PDFページ1 =裏表紙; PDFページ2 =ページ2と3など。これは画面上では問題なく読み取れますが、印刷してから印刷することはできません。小冊子のコピーを作成するには、ホチキスで止めます。

これを両面コピー機で印刷できるようにする必要がありました。つまり、印刷できるように「面付け」されたPDFに戻します。そこで、カートのソリューションを使用して、この(エヘム)「ワンライナー」を作成し、正しいページ順序でハーフページに戻しました。任意の高さと幅、および任意の数のページで機能します。私の場合、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を「印刷」し、それを「小冊子の作成」に送信します"ツール(私の場合、ChristophVogelbuschのCreateBooklet for Macを http://download.cnet.com/Create-Booklet/3000-2088_4-86349.html から使用しました)。

結果のPDFは、1枚あたり2ページで11 x 8.5の元のページサイズに戻りますが、両面、短辺の綴じで印刷できるように順序付けられます。 、そしてほら、あなたはコピーして折り、中綴じできるプリントアウトを手に入れ、オリジナルを分解することなく(あるいは必ずしも見ることさえせずに)オリジナルのブックレットを再現します。

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

-c

2
Chris Thorman

左側の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
1
mulllhausen

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

Windowsでは、最初に1つのカバー画像でレターサイズのPDFを分割する場合、次のことがうまくいきました(2番目のステップで[-612 0]を使用すると、間違った方向にプッシュされたため、正の値で空白ページが作成されました。 。)

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

-dFirstPage=2の使用に注意してください。これは、2ページ目でgsに処理を開始するように指示します。

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をアルファベット順に結合します(幸いにも、正しい順序で並べ替えられていることを意味します)。また、結果をghostscriptで再度実行して、「警告:世代番号が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
Louis