Ferramenta baseada em Linux para cortar PDFs em várias páginas [closed]

15

Eu tenho um monte de arquivos PDF que foram produzidos duas páginas "reais" para uma única página PDF; Eu gostaria de cortá-las ao meio e colocar cada metade em uma página separada. Essencialmente, preciso de algo que faça exatamente o oposto de pdfnup (ou psnup ). O Google e a pesquisa do apt-cache não estão me dando amor.

Plataforma é Linux, código aberto preferido; como eu tenho uma grande pilha deles para fazer algo que pode ser roteirizado (ao contrário de uma GUI) seria legal, então eu posso apenas dar uma lista deles e mandar embora.

Um script pré-existente não é a única opção; se houver um código de exemplo para manipular PDFs de maneira semelhante com uma biblioteca de terceiros, provavelmente posso ativá-lo para fazer o que eu quero.

    
por womble 22.09.2010 / 07:14

6 respostas

22

Você pode resolver isso com a ajuda do Ghostscript. pdftk sozinho não pode fazer isso (até onde eu sei). Vou te dar os passos da linha de comando para fazer isso manualmente. Será fácil roteirizar isso como um procedimento, também com parâmetros diferentes para tamanhos de página e números de página. Mas você disse que pode fazer isso sozinho;)

Como resolver isso com a ajuda do Ghostscript ...

... e por diversão, eu recentemente fiz não com um arquivo de entrada com páginas "double-up", mas uma com "treble-ups". Você pode ler a resposta para este caso aqui .

Seu caso é ainda mais simples. Você parece ter algo parecido com isso:

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

Você deseja criar um PDF com 4 páginas, cada uma com o tamanho de 421 pt x 595 pt.

Primeiro passo

Vamos primeiro extrair as seções à esquerda de cada uma das páginas de entrada:

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

O que esses parâmetros fazem?

Primeiro, saiba que em PDF 1 polegada == 72 pontos . Então o resto é:

  • -o ...............: Nomeia o arquivo de saída. Implicitamente também usa -dBATCH -dNOPAUSE -dSAFER .
  • -sDEVICE=pdfwrite : queremos PDF como formato de saída.
  • -g................: define o tamanho da mídia de saída em pixels. A resolução padrão do pdfwrite é de 720 dpi. Por isso, multiplique por 10 para obter uma correspondência para PageOffset.
  • -c "..............: pede ao Ghostscript para processar o trecho de código PostScript fornecido antes do arquivo de entrada principal (que precisa seguir com -f ).
  • <</PageOffset ....: configura o deslocamento da imagem da página no meio. (Claro que, para as páginas da esquerda, a mudança de [0 0] não tem efeito real.)
  • -f ...............: processa este arquivo de entrada.

Qual foi o resultado do último comando?

Este aqui:

Output file: left-sections.pdf, page 1
+------------+  ^
|            |  |
|     1      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

Output file: left-sections.pdf, page 2
+------------+  ^
|            |  |
|     3      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v
<-- 421 pt -->

Segundo passo

Em seguida, as seções certas:

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

Observe o deslocamento negativo, pois estamos deslocando a página para a esquerda enquanto mantemos a área de visualização parada.

Resultado:

Output file: right-sections.pdf, page 1
+------------+  ^
|            |  |
|     2      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

Output file: right-sections.pdf, page 2
+------------+  ^
|            |  |
|     4      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v
<-- 421 pt -->

Última etapa

Agora combinamos as páginas em um único arquivo. Poderíamos fazer isso com ghostscript também, mas usaremos pdftk , porque é mais rápido para esse trabalho:

pdftk \
  A=right-sections.pdf \
  B=left-sections.pdf \
  shuffle \
  output single-pages-output.pdf
  verbose

Concluído. Aqui está o resultado desejado. 4 páginas diferentes, tamanho 421x595 pt.

Resultado:

+------------+ +------------+ +------------+ +------------+   ^
|            | |            | |            | |            |   |
|     1      | |     2      | |     3      | |     4      |   |
|            | |            | |            | |            |5595 pt
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
+------------+ +------------+ +------------+ +------------+   v
<-- 421 pt --> <-- 421 pt --> <-- 421 pt --> <-- 421 pt -->
    
por 24.09.2010 / 14:05
5

Existe uma ferramenta pdfposter que pode ser usada para criar PDFs com várias páginas para uma página de entrada (colocar ou cortar Páginas). É semelhante à ferramenta poster , que faz o mesmo para arquivos PostScript.

    
por 22.03.2012 / 15:26
2

Então, depois de pesquisar muito mais (parece que "páginas cortadas em PDF" é uma pesquisa muito melhor), encontrei um pequeno script chamado unpnup que usa poster , conversão PDF / PS e pdftk para fazer exatamente o que eu preciso. É um pouco longo, mas é muito superior aos outros métodos que encontrei (como usar o imagemagick) porque não rasteriza as páginas antes de cuspi-las.

Apenas no caso de o mobileread desaparecer por algum motivo, o núcleo do script (licenciado sob a GPLv2 ou posterior por Harald Hackenberg <hackenberggmx.at> ) é o seguinte:

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
    
por 22.09.2010 / 21:58
2

Eu achei a resposta de Kurt Pfeifle muito útil para minha situação semelhante. Achei que poderia compartilhar minha modificação da solução com outras pessoas ...

Eu também tinha um PDF digitalizado com duas páginas em cada folha. Foi uma digitalização de 11 x 8,5 polegadas (polegadas) de um livreto grampeado na lombada que foi deixado grampeado quando digitalizado originalmente, portanto: Página 1 do PDF = tampa traseira e frontal; PDF página 2 = páginas 2 e 3, etc. Isso é exibido na tela, mas não é possível imprimi-lo e depois grampear para fazer mais cópias do livreto.

Eu precisava imprimir isso em uma copiadora duplex; ou seja, transformá-lo de volta em um PDF "imposto", pronto para impressão. Então, usando a solução de Kurt, eu fiz esse "one-liner" para convertê-lo de volta em meia página, na ordem correta das páginas novamente. Ele funcionará para qualquer ALTURA e LARGURA e também para qualquer número de páginas. No meu caso, eu tinha um livreto de 40 páginas (20 páginas escaneadas no PDF).

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"

Você só precisa alterar os primeiros parâmetros neste comando para especificar HEIGHT e WIDTH e ORIG_FILE_PATH. O restante do comando calcula os vários tamanhos e chama gs duas vezes, depois pdftk. Ele contará até mesmo as páginas em sua varredura e produzirá a especificação de classificação correta (para o cenário que eu forneci).

Isso gera algum progresso sobre o que está fazendo, que será assim:

+++ 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

Em seguida, para obter a imposição de página necessária para um livreto impresso, basta "imprimir" ordered.pdf em um tamanho de página personalizado exatamente do tamanho necessário (no meu exemplo, 5,5 x 8,5), enviando-o para um "booklet making" tool (no meu caso, eu usei o livro Create Booklet for Mac de Christoph Vogelbusch de link ).

O PDF resultante voltará ao tamanho da página original de 11 x 8,5 com 2 páginas por folha, mas a ordem será tal que você poderá imprimir em frente e verso, em encadernação de margem curta e voilà! você terá uma impressão que poderá fotocopiar e dobrar e costurar na lombada, reproduzindo o livreto original sem nunca desmontar (ou mesmo necessariamente ver) o original.

Espero que isso ajude alguém!

-c

    
por 01.09.2012 / 06:47
1

Com base na resposta piptas ' acima:

No Windows, para dividir PDFs em tamanho carta com uma única imagem de capa no início, o seguinte funcionou muito bem para mim (observe o uso de [-612 0] na segunda etapa, um valor positivo criou páginas em branco porque o caminho errado.)

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

Observe o uso de -dFirstPage=2 , que instrui o gs a começar o processamento na página 2.

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

Isso cria o direito-seções.pdf da mesma maneira. E agora a imagem da capa:

gswin32c -o cover.pdf -sDEVICE=pdfwrite -dLastPage=1 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

Em seguida, como eu não queria mesclar com o pdftk usando a entrada de página manual, divido as seções esquerda e direita em PDFs separados em um novo diretório.

mkdir input_file
copy cover.pdf input_file
pdftk input_file\*.pdf cat output input_temp.pdf
gswin32c -o final_output.pdf -sDEVICE=pdfwrite -f input_temp.pdf
00.pdf pdftk left-sections.pdf burst output input_file\%04d_A.pdf pdftk right-sections.pdf burst output input_file\%04d_B.pdf

Em seguida, participo dos PDFs nesse diretório, em ordem alfabética (e felizmente isso significa que eles estão classificados na ordem correta!) e também executo o resultado por meio do ghostscript novamente para corrigir "Aviso: Número de geração de 0.65535 faixa, assumindo 0. " erros produzidos pelo pdftk que ghostscript chamado "itext-paulo-155 (itextpdf.sf.net-lawagie.com)" - também aconteceu para cortar o tamanho do arquivo pela metade no meu uso. Com um original de 4.5MB, o resultado do pdftk foi de 6.7MB e o reprocessamento do gswin32c reduziu para 3.2MB.

mkdir input_file
copy cover.pdf input_file
pdftk input_file\*.pdf cat output input_temp.pdf
gswin32c -o final_output.pdf -sDEVICE=pdfwrite -f input_temp.pdf
00.pdf pdftk left-sections.pdf burst output input_file\%04d_A.pdf pdftk right-sections.pdf burst output input_file\%04d_B.pdf

E terminamos! Sinta-se à vontade para excluir a pasta input_file, cover.pdf, input_temp.pdf, right_sections.pdf e left_sections.pdf. ; -)

    
por 07.11.2010 / 19:49
1

Se você só precisa imprimir os PDFs do lado esquerdo em um documento, e os PDFs do lado direito em um documento, então o seguinte script baseado na resposta de Kurt Pfeifle fará o truque qualquer altura e largura):

$ 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"

execute-o da seguinte maneira:

$ ./split.sh thepdftosplit.pdf
    
por 11.11.2014 / 09:35