pdfcrop ですべてのページを同じサイズで出力するにはどうすればよいですか?

pdfcrop ですべてのページを同じサイズで出力するにはどうすればよいですか?

Beamer にインポートするために PDF に変換した PowerPoint アニメーションをトリミングしようとしていますが (ppsplit を使用)、pdfcrop(texlive から) 実行して空白を減らすと、ページが個別にトリミングされ、各ページのサイズが異なります。すべてのページを最大ページと同じサイズにする方法はありますか?

答え1

フラグは各ステップで使用される境界ボックスを出力することがわかりました--verbose。これは「成長する」アニメーションなので、最後のページが最大になります。

そのため、すべてを同じサイズにするために、--verbose を指定して pdfcrop を実行し、次の出力を抽出しました。

%%HiResBoundingBox: 48.000022 299.872046 624.124950 420.127932

そして、それを pdfcrop の 2 回目の実行に渡して、境界ボックスを指定します。

pdfcrop --bbox "48.000022 299.872046 624.124950 420.127932" ~/animation.pdf

答え2

shこれは、すべての PDF ページを同じサイズにトリミングするシェル関数です。この関数はpdfcropおよび GNUに依存しているdatamashため、必ずインストールしてください。

pdfconstcrop() {
    pdfcrop --bbox "$(
        pdfcrop --verbose "$@" |
        grep '^%%HiResBoundingBox: ' |
        cut -d' ' -f2- |
        LC_ALL=C datamash -t' ' min 1 min 2 max 3 max 4
    )" "$@"
}

上記のコード ブロックをターミナルにコピーして貼り付け、 のpdfconstcrop代わりにを使用しますpdfcrop。通常のpdfcropオプションも引き続き機能します。例をいくつか示します。

  • pdfconstcrop in.pdf結果を に書き込みますin-crop.pdf
  • pdfconstcrop in.pdf out.pdf結果を書き込むout.pdf
  • pdfconstcrop --margins 50 in.pdf両側に(少なくとも)50ptの余白を残します。

答え3

最後のページが最大でない場合は、すべてのページの中で最大の幅と高さを計算し、これらの値を使用して適切な境界ボックスを決定する必要があります。境界ボックス内の 4 つの座標は次のようになります。

  • 左上隅のx座標(ページの左端からの距離)、
  • 左上隅のy座標(ページ上端からの距離)、
  • 右下隅のx座標(ページの左端からの距離)、
  • 右下隅の y 座標 (ページの上端からの距離)。

各ページの適切な境界ボックスを計算してそれを使用することは、スクリプトに適切なパッチを適用することで実行できますpdfcrop(スクリプトは Perl で書かれています)。ただし、私は Perl にあまり慣れていないため、代わりに Python で実行しました。誰かの役に立つかもしれないので、ここにスクリプトを示します。

import re, sys
lines = sys.stdin.readlines()
width = height = 0
# First pass: compute |width| and |height|.
for line in lines:
  m = re.match(r'\\page (\d*) \[([0-9.]*) ([0-9.]*) ([0-9.]*) ([0-9.]*)\](.*)', line, re.DOTALL)
  if m:
    page, xmin, ymin, xmax, ymax, rest = m.groups()
    width = max(width, float(xmax) - float(xmin))
    height = max(height, float(ymax) - float(ymin))
# Second pass: change bounding boxes to have width |width| and height |height|.
for line in lines:
  m = re.match(r'\\page (\d*) \[([0-9.]*) ([0-9.]*) ([0-9.]*) ([0-9.]*)\](.*)', line, re.DOTALL)
  if m:
    page, xmin, ymin, xmax, ymax, rest = m.groups()
    xmin = float(xmin)
    ymin = float(ymin)
    xmax = float(xmax)
    ymax = float(ymax)
    # We want |xmin| and |xmax| such that their difference is |width|
    addx = (width - (xmax - xmin)) / 2.0
    xmin -= addx
    xmax += addx
    # We want |ymin| and |ymax| such that their difference is |height|
    addy = (height - (ymax - ymin)) / 2.0
    ymin -= addy
    ymax += addy
    sys.stdout.write(r'\page %s [%s %s %s %s]%s' % (page, xmin, ymin, xmax, ymax, rest))
  else:
    sys.stdout.write(line)

使用法:

  1. 通常のpdfcropコマンドを実行します。--debug例:

    pdfcrop --debug foo.pdf
    

    のため--debug、作成されたファイルは削除されません。また、に特別なオプションを渡していた場合は、最後に実行されたコマンド (または任意のコマンド)tmp-pdfcrop-*.texを書き留めてください。これは簡単なことではありません。pdftexpdfcrop

  2. tmp-pdfcrop-*上記のスクリプトにファイルを渡します。例:

    python find-common.py < tmp-pdfcrop-34423.tex > tmp-pdfcrop-common.tex
    

    tmp-pdfcrop-common.texこれにより、異なる境界ボックスを使用して書き出されます。

  3. pdftex次のファイルを使用して、呼び出されたコマンド (またはその他のコマンド)を実行しますpdfcrop

    pdftex -no-shell-escape -interaction=nonstopmode tmp-pdfcrop-common.tex
    
  4. 結果の PDF ファイルを確認し、任意の名前に変更します。

    mv tmp-pdfcrop-common.pdf foo-crop.pdf
    

答え4

質問に理想的に適合すると思われる Python パッケージがあります:https://github.com/abarker/pdfCropMargins

たとえば、次のコマンド:

$ pdf-crop-margins -u -s in.pdf

in.pdfすべてのページが同じサイズに設定され、すべてのページで切り取り量が均一になるように切り取られ、デフォルトでは既存の余白の 10% が保持されます。出力ファイルは入力ファイルとほぼ同じサイズで、リンクや注釈も保持されます。

関連情報