如何使 pdfcrop 輸出相同大小的所有頁面?

如何使 pdfcrop 輸出相同大小的所有頁面?

我正在嘗試裁剪一個powerpoint動畫,將其轉換為pdf以導入到beamer中(使用ppsplit),但是當我運行pdfcrop(從texlive)以減少空白時,它會單獨裁剪頁面,使每個頁面的大小不同。有沒有辦法讓所有頁面的大小與最大頁面的大小相同?

答案1

我發現該--verbose標誌將輸出每一步使用的邊界框。由於這是一個“成長”動畫,因此最後一頁是最大的。

因此,為了使它們全部具有相同的大小,我使用 --verbose 運行 pdfcrop 並提取了以下輸出:

%%HiResBoundingBox: 48.000022 299.872046 624.124950 420.127932

然後將其輸入第二次運行的 pdfcrop,指定邊界框:

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

答案2

這是一個shshell 函數,用於將所有 pdf 頁面裁剪為相同大小。該功能依賴pdfcropGNU 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

如果最後一頁不是最大的,我們需要計算所有頁面中的最大寬度和高度,然後使用這些值來確定正確的邊界框。請注意,邊界框中的四個座標是:

  • 左上角的 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建立的檔案。另外,如果您傳遞了一些特殊選項,請記下pdftex它最後執行的(或其他)命令,pdfcrop因此這很重要。

  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%。輸出檔案的大小與輸入檔案和連結大致相同,註釋也被保留。

相關內容