Como faço para que o pdfcrop produza todas as páginas do mesmo tamanho?

Como faço para que o pdfcrop produza todas as páginas do mesmo tamanho?

Estou tentando cortar uma animação do PowerPoint que converti para pdf para importar para o beamer (usando ppsplit), mas quando executo pdfcrop(do texlive) para reduzir o espaço em branco, ele corta as páginas individualmente, de modo que cada página tenha um tamanho diferente. Existe uma maneira de fazer com que todas as páginas tenham o mesmo tamanho da página maior?

Responder1

Descobri que o --verbosesinalizador exibirá a caixa delimitadora usada em cada etapa. Como se trata de uma animação "crescente", a última página é a maior.

Então, para que todos tenham o mesmo tamanho, executei o pdfcrop com --verbose e extraí esta saída:

%%HiResBoundingBox: 48.000022 299.872046 624.124950 420.127932

e depois alimentei isso em uma segunda execução do pdfcrop, especificando a caixa delimitadora:

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

Responder2

Aqui está uma shfunção shell para cortar todas as páginas PDF no mesmo tamanho. A função depende de pdfcrope GNU datamash, então certifique-se de instalá-los.

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

Copie e cole o bloco de código acima em seu terminal e simplesmente use pdfconstcropem vez de pdfcrop. As pdfcropopções usuais ainda funcionam. Alguns exemplos:

  • pdfconstcrop in.pdfescreve o resultado em in-crop.pdf.
  • pdfconstcrop in.pdf out.pdfescreve o resultado emout.pdf
  • pdfconstcrop --margins 50 in.pdfdeixa (pelo menos) margens de 50 pontos em cada lado.

Responder3

Se a última página não for a maior, precisamos calcular a largura e a altura máximas entre todas as páginas e, em seguida, usar esses valores para determinar as caixas delimitadoras corretas. Observe que as quatro coordenadas em uma caixa delimitadora são:

  • coordenada x (distância da borda esquerda da página) do canto superior esquerdo,
  • coordenada y (distância da borda superior da página) do canto superior esquerdo,
  • coordenada x (distância da borda esquerda da página) do canto inferior direito,
  • Coordenada y (distância da borda superior da página) do canto inferior direito.

Calcular as caixas delimitadoras corretas para cada página e usá-las poderia ser feito com um patch apropriado para o pdfcropscript (está escrito em Perl), mas como não estou muito confortável com Perl, fiz isso em Python; aqui está o script caso seja útil para alguém.

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. Execute o pdfcropcomando normal, com --debug, por exemplo:

    pdfcrop --debug foo.pdf
    

    Por causa disso --debug, ele não excluirá o tmp-pdfcrop-*.texarquivo que criou. Além disso, anote o pdftexcomando (ou qualquer outro) que ele executou no final, se você passou algumas opções especiais pdfcrope, portanto, não é trivial.

  2. Passe o tmp-pdfcrop-*arquivo pelo script acima, por exemplo:

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

    Isto irá escrever tmp-pdfcrop-common.texcom diferentes caixas delimitadoras.

  3. Execute o pdftexcomando (ou qualquer outro) que pdfcropchamou, com este arquivo:

    pdftex -no-shell-escape -interaction=nonstopmode tmp-pdfcrop-common.tex
    
  4. Verifique o arquivo PDF resultante e renomeie-o como desejar:

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

Responder4

Existe um pacote Python que acho que se adapta idealmente à pergunta feita:https://github.com/abarker/pdfCropMargins

Por exemplo o comando:

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

recortes in.pdfpara que todas as páginas sejam definidas com o mesmo tamanho e a quantidade de corte seja uniforme em todas as páginas, mantendo por padrão 10% das margens existentes. O arquivo de saída tem aproximadamente o mesmo tamanho do arquivo de entrada e dos links; as anotações também são preservadas.

informação relacionada