Dividir páginas em pdf

67

Eu tenho um arquivo pdf digitalizado que digitalizou duas páginas em uma página virtual (página em arquivo pdf).

A resolução é de boa qualidade. O problema é que tenho que aumentar o zoom ao ler e arrastar da esquerda para a direita.
Existe algum comando ( convert, pdftk...) ou script que pode converter este arquivo pdf com páginas normais (uma página do livro = uma página no arquivo pdf)?

xralf
fonte
11
Embora não seja a resposta mais votada, essa realmente me surpreendeu. É simples, curto, rápido e elegante. Eu pensei que era vale a pena mencioná-lo aqui, como às vezes somos preguiçosos demais para se deslocar até outras respostas ...
Peque
Para os registros, a operação reversa (associação de várias páginas) pode ser obtida na linha de comando (em vez de "imprimir em arquivo") com pdfnup, do pdfjamconjunto.
Skippy le Grand Gourou

Respostas:

46

Aqui está um pequeno script Python usando a biblioteca PyPdf que faz o trabalho perfeitamente. Salve-o em um script chamado un2up(ou o que você quiser), torne-o executável ( chmod +x un2up) e execute-o como um filtro ( un2up <2up.pdf >1up.pdf).

#!/usr/bin/env python
import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
input = PdfFileReader(sys.stdin)
output = PdfFileWriter()
for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
    q = copy.copy(p)
    (w, h) = p.mediaBox.upperRight
    p.mediaBox.upperRight = (w/2, h)
    q.mediaBox.upperLeft = (w/2, h)
    output.addPage(p)
    output.addPage(q)
output.write(sys.stdout)

Ignore todos os avisos de descontinuação; somente os mantenedores do PyPdf precisam se preocupar com isso.

Se a entrada for orientada de maneira incomum, talvez seja necessário usar coordenadas diferentes ao truncar as páginas. Consulte Por que meu código não divide corretamente todas as páginas em um pdf digitalizado?


Para o caso de ser útil, aqui está minha resposta anterior, que usa uma combinação de duas ferramentas mais alguma intervenção manual:

  • Pdfjam (pelo menos versão 2.0), baseado no pacote LaTeX das páginas pdf , para cortar as páginas;
  • Pdftk , para juntar as metades esquerda e direita.

Ambas as ferramentas são necessárias porque, até onde sei, as páginas em pdf não conseguem aplicar duas transformações diferentes à mesma página em um fluxo. Na chamada para pdftk, substitua 42 pelo número de páginas no documento de entrada ( 2up.pdf).

pdfjam -o odd.pdf --trim '0cm 0cm 14.85cm 0cm' --scale 1.141 2up.pdf
pdfjam -o even.pdf --trim '14.85cm 0cm 0cm 0cm' --scale 1.141 2up.pdf
pdftk O=odd.pdf E=even.pdf cat $(i=1; while [ $i -le 42 ]; do echo O$i E$i; i=$(($i+1)); done) output all.pdf

Caso você não possua o pdfjam 2.0, basta instalar o PDFLaTeX com o pacote pdfpages (no Ubuntu: você precisa do texlive-latex-recommended Instale o texlive-latex recomendado e talvez (no Ubuntu: texlive-fonts-recommended Instale o texlive-fonts-recomendado ) e use o seguinte driver arquivo driver.tex:

\batchmode
\documentclass{minimal}
\usepackage{pdfpages}
\begin{document}
\includepdfmerge[trim=0cm 0cm 14.85cm 0cm,scale=1.141]{2up.pdf,-}
\includepdfmerge[trim=14.85cm 0cm 0cm 0cm,scale=1.141]{2up.pdf,-}
\end{document}

Em seguida, execute os seguintes comandos, substituindo 42 pelo número de páginas no arquivo de entrada (que deve ser chamado 2up.pdf):

pdflatex driver
pdftk driver.pdf cat $(i=1; pages=42; while [ $i -le $pages ]; do echo $i $(($pages+$i)); i=$(($i+1)); done) output 1up.pdf
Gilles 'SO- parar de ser mau'
fonte
A biblioteca PyPdf funciona perfeitamente. Eu apenas mudei um pouco e executei com python conv_pdf.py res.pdf . Como você executaria seu script shebang na linha de comando?
Xralf
Gostaria de experimentar a versão com o pdfjam (por causa de uma pequena escala) também, mas após a instalação do pacote pdfjam, meu shell não reconhecerá o pdfjamcomando.
Xralf
@xralf: Meu script python apenas lê da entrada padrão e grava na saída padrão. A versão pdfjam requer pdfjam 2.0; é apenas um pequeno invólucro em torno de páginas pdf, e eu adicionei o pouco de LaTeX que ele gera para que você possa usá-lo diretamente. O problema de dimensionamento é provavelmente solucionável com o pypdf, pode ser um problema de tamanho de página (eu posso ou não ser capaz de ajudar se você fornecer mais detalhes sobre o que está acontecendo e, especialmente, os tamanhos de página envolvidos).
Gilles 'SO- stop be evil'
Obrigado, a diferença está na resolução um pouco pior, mas isso não importa. Voltarei a ele quando souber mais sobre o látex (agora é muito complexo para mim e a solução é realmente boa com o PyPdf).
Xralf
11
Script útil @Gilles Versy. Eu esperava ver algo assim em pdfjam, pdftk. De qualquer forma, algumas pessoas podem querer algumas modificações para dividir as páginas em outros eixos e usar ordens diferentes. Isso é possível com a alteração de algumas linhas e o uso deq.mediaBox.lowerRight = (w, h/2)
ony
52

Apenas uma adição, já que tive problemas com o script python (e várias outras soluções): para mim mutoolfuncionou muito bem. É uma adição simples e pequena, fornecida com o elegante mupdfleitor. Então você pode tentar:

mutool poster -y 2 input.pdf output.pdf

Para divisões horizontais, substitua ypor x. E você pode, é claro, combinar os dois para soluções mais complexas.

Realmente feliz por ter encontrado isso (depois de anos de uso diário de mupdf :)

mutoolvem com mupdf a partir da versão 1.4: http://www.mupdf.com/news


Instalando mupdfe mutoolde origem:

wget http://www.mupdf.com/downloads/mupdf-1.8-source.tar.gz
tar -xvf mupdf-1.8-source.tar.gz
cd mupdf-1.8-source
sudo make prefix=/usr/local install

Ou vá para a página de downloads para encontrar uma versão mais recente.

martz
fonte
3
Eu tinha um djvu ... eu o transformei em um postscript (bastante rápido), depois em um pdf (tartaruga lenta) - e finalmente o mutool cortou tão rápido que achei que não funcionaria - funcionou!
Julien Puydt
2
Sim, também fiquei muito satisfeito com a velocidade.
martz
3
Este é o mais fácil e melhor. mutoolfoi feito para isso. Além disso, cuidado -y, acho que na maioria dos casos o que você quer é -x.
Fiatjaf
2
Este utilitário é muito rápido, no entanto, tenho um problema com a ordem das páginas. O comando aloca a página direita na primeira posição e a página esquerda na segunda. Alguém pode me ajudar com esse problema?
garciparedes
16

O Imagemagick pode fazer isso em uma etapa:

$ convert in.pdf -crop 50%x0 +repage out.pdf
tomas
fonte
11
Obrigado. Se eu adicionar o -density 400parâmetro, ele tem uma qualidade ainda melhor.
Xralf
11
Parece que o convert usa raster como um formato intermediário. Isso causa uma aparência borrada, mesmo quando o PDF original contém objetos vetoriais.
ony
Alguém sabe como fazer isso sem rasterizar o conteúdo da página ao longo do caminho ... ou pelo menos para definir uma resolução mais alta?
Tomislav Nakic-Alfirevic
isso traduziu textos em imagens e criou pdf a partir de imagens. Talvez seja bom para fotos, mas inútil para extração de texto.
22417 Andrej
6

O comando Convert do ImageMagick pode ajudá-lo a cortar seu arquivo em 2 partes. Consulte http://www.imagemagick.org/Usage/crop/

Se eu fosse você, escreveria um script (shell) como este:

  1. Divida o seu arquivo com pdfsam : 1 página = 1 arquivo no disco (o formato não importa. Escolha um que o ImageMagick conheça. Gostaria apenas de usar PS ou PDF.
  2. Para cada página, corte a primeira metade e coloque-a em um arquivo chamado $ {PageNumber} A

  3. Corte a segunda metade e coloque-a em um arquivo chamado $ {PageNumber} B.

    Você obtém 1A.pdf, 1B.pdf, 2A.pdf, 2B.pdf, etc.

  4. Agora, monte isso novamente em um novo PDF. Existem muitos métodos para fazer isso.
tiktak
fonte
11
Usar o ImageMagick não rasterizará os arquivos? E você deve explicar a última parte em linha, especialmente para o benefício dos não-francófonos na platéia.
Gilles 'SO- stop be evil'
Porque você não precisa entender francês. Apenas mostra como você pode usar o convert, pdftk ou ghostscript (gs) do ImageMagick sozinho para atingir esse objetivo. Eu gosto de usar o pdftk. "Rasterização" não importa, pois é um documento digitalizado.
tiktak
6

Com base nas respostas de Gilles e em como encontrar a contagem de páginas em PDF que escrevi

#!/bin/bash

pdforiginal=$1
pdfood=$pdforiginal.odd.pdf
pdfeven=$pdforiginal.even.pdf
pdfout=output_$1
margin=${2:-0}
scale=${3:-1}

pages=$(pdftk $pdforiginal dump_data | grep NumberOfPages | awk '{print $2}')

pagesize=$(pdfinfo $pdforiginal | grep "Page size" | awk '{print $5}')
margin=$(echo $pagesize/2-$margin | bc -l)

pdfjam -o $pdfood --trim "0cm 0cm ${margin}pt 0cm" --scale $scale $pdforiginal
pdfjam -o $pdfeven --trim "${margin}pt 0cm 0cm 0cm" --scale $scale  $pdforiginal

pdftk O=$pdfood E=$pdfeven cat $(i=1; while [ $i -le $pages ]; do echo O$i E$i; i=$(($i+1)); done) output $pdfout

rm $pdfood $pdfeven

Para que eu possa correr

./split.sh my.pdf 50 1.2

onde 50 para ajustar margem e 1,2 para escala.

Anton Bessonov
fonte
4

Aqui está uma variação do código PyPDF publicado por Gilles. Esta função funcionará independentemente da orientação da página:

import copy
import math
import pyPdf

def split_pages(src, dst):
    src_f = file(src, 'r+b')
    dst_f = file(dst, 'w+b')

    input = pyPdf.PdfFileReader(src_f)
    output = pyPdf.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i)
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.mediaBox.lowerLeft
        x3, x4 = p.mediaBox.upperRight

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)
        x5, x6 = math.floor(x3/2), math.floor(x4/2)

        if x3 > x4:
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical
            p.mediaBox.upperRight = (x3, x4)
            p.mediaBox.lowerLeft = (x1, x6)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()
moraes
fonte
2

A melhor solução foi o mutool, veja acima:

sudo apt install mupdf-tools pdftk

o separamento:

mutool poster -y 2 input.pdf output.pdf

mas você precisa girar as páginas restantes:

pdftk output.pdf cat 1-endleft output rotated.pdf
Eduard Florinescu
fonte
Ainda sem sobreposição ...
MUY Bélgica
1

Com base na resposta de Benjamin no AskUbuntu, eu recomendaria o uso da ferramenta GUI chamada gscan2pdf .

  1. Importe o arquivo de digitalização de PDF para gscan2pdf. Observe que arquivos PDF sem imagem podem não funcionar. As digitalizações são boas, assim você não precisa se preocupar.

    insira a descrição da imagem aqui

  2. Pode demorar um pouco, dependendo do tamanho do documento. Espere até carregar.

  3. Pressione Ctrl + A para selecionar todas as páginas e, em seguida, gire (Ctrl + Shift + C), se necessário.

    insira a descrição da imagem aqui

  4. Vá para Ferramentas >> Limpeza . Selecione Layout como páginas duplas e # saída = 2 .

    insira a descrição da imagem aqui

  5. Clique em OK e aguarde até o trabalho terminar.

    insira a descrição da imagem aqui

  6. Salve o arquivo PDF. Feito.

Nanashi No Gombe
fonte
Testado, falhou com documentos PDF complexos com uma enorme quantidade de imagens.
MUY Belgium
0

Moraes solução não funcionou para mim. O principal problema foi o cálculo de x5 e x6. Aqui um deslocamento deve ser considerado, ou seja, se lowerLeft não estiver em (0,0)

Então, aqui está outra variação, com adaptações adicionais para usar PyPDF2 e python 3:

import copy
import math
import PyPDF2
import sys
import io 

def split_pages(src, dst):
    src_f = io.open(src, 'r+b')
    dst_f = io.open(dst, 'w+b')

    input = PyPDF2.PdfFileReader(src_f)
    output = PyPDF2.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i) 
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.cropBox.lowerLeft
        x3, x4 = p.cropBox.upperRight        

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)

        x5 = math.floor((x3-x1) / 2 + x1)
        x6 = math.floor((x4-x2) / 2 + x2)

        if x3 > x4:        
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical        
            p.mediaBox.lowerLeft = (x1, x6)
            p.mediaBox.upperRight = (x3, x4)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()

if __name__ == "__main__":
    if ( len(sys.argv) != 3 ):
        print ('Usage: python3 double2single.py input.pdf output.pdf')
        sys.exit(1)

    split_pages(sys.argv[1], sys.argv[2])
vbar
fonte