¿Cómo hago para que pdfcrop genere todas las páginas del mismo tamaño?

¿Cómo hago para que pdfcrop genere todas las páginas del mismo tamaño?

Estoy intentando recortar una animación de PowerPoint que convertí a PDF para importarla a Beamer (usando ppsplit), pero cuando ejecuto pdfcrop(desde texlive) para reducir el espacio en blanco, recorta las páginas individualmente de modo que cada página tenga un tamaño diferente. ¿Hay alguna manera de lograr que todas las páginas tengan el mismo tamaño que la página más grande?

Respuesta1

Descubrí que la --verbosebandera generará el cuadro delimitador utilizado en cada paso. Dado que se trata de una animación "en crecimiento", la última página es la más grande.

Entonces, para que todos tuvieran el mismo tamaño, ejecuté pdfcrop con --verbose y extraje este resultado:

%%HiResBoundingBox: 48.000022 299.872046 624.124950 420.127932

y luego lo alimentó a una segunda ejecución de pdfcrop, especificando el cuadro delimitador:

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

Respuesta2

Aquí hay una shfunción de shell para recortar todas las páginas PDF al mismo tamaño. La función depende de pdfcropGNU datamash, así que asegúrese de instalarlos.

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

Copie y pegue el bloque de código anterior en su terminal y luego simplemente use pdfconstcropen lugar de pdfcrop. Las opciones habituales pdfcropsiguen funcionando. Algunos ejemplos:

  • pdfconstcrop in.pdfescribe el resultado en in-crop.pdf.
  • pdfconstcrop in.pdf out.pdfescribe el resultado enout.pdf
  • pdfconstcrop --margins 50 in.pdfdeja (al menos) márgenes de 50 puntos a cada lado.

Respuesta3

Si la última página no es la más grande, debemos calcular el ancho y alto máximos entre todas las páginas y luego usar estos valores para determinar los cuadros delimitadores correctos. Tenga en cuenta que las cuatro coordenadas en un cuadro delimitador son:

  • Coordenada x (distancia desde el borde izquierdo de la página) de la esquina superior izquierda,
  • Coordenada y (distancia desde el borde superior de la página) de la esquina superior izquierda,
  • coordenada x (distancia desde el borde izquierdo de la página) de la esquina inferior derecha,
  • Coordenada y (distancia desde el borde superior de la página) de la esquina inferior derecha.

Calcular los cuadros delimitadores correctos para cada página y usarlos se podría hacer con un parche apropiado en el pdfcropscript (está escrito en Perl), pero como no me siento muy cómodo con Perl, lo hice en Python; Aquí está el script por si a alguien le resulta útil.

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)

Uso:

  1. Ejecute el pdfcropcomando normal, con --debug, por ejemplo:

    pdfcrop --debug foo.pdf
    

    Debido a --debug, no eliminará el tmp-pdfcrop-*.texarchivo que creó. Además, anote el pdftexcomando (o lo que sea) que ejecutó al final, si le había pasado algunas opciones especiales pdfcropy, por lo tanto, no es trivial.

  2. Pase el tmp-pdfcrop-*archivo a través del script anterior, por ejemplo:

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

    Esto se escribirá tmp-pdfcrop-common.texcon diferentes cuadros delimitadores.

  3. Ejecute el pdftexcomando (o lo que sea) que pdfcropllamó con este archivo:

    pdftex -no-shell-escape -interaction=nonstopmode tmp-pdfcrop-common.tex
    
  4. Verifique el archivo PDF resultante y cámbiele el nombre como desee:

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

Respuesta4

Hay un paquete de Python que creo que se ajusta idealmente a la pregunta formulada:https://github.com/abarker/pdfCropMargins

Por ejemplo el comando:

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

recortes in.pdfpara que todas las páginas tengan el mismo tamaño y la cantidad de recorte sea uniforme en todas las páginas, conservando de forma predeterminada el 10% de los márgenes existentes. El archivo de salida tiene aproximadamente el mismo tamaño que el archivo de entrada y los enlaces, las anotaciones también se conservan.

información relacionada