Dividir páginas en pdf

67

Tengo un archivo pdf escaneado que ha escaneado dos páginas en una página virtual (página en archivo pdf).

La resolución es de buena calidad. El problema es que tengo que hacer zoom al leer y arrastrar de izquierda a derecha.
¿Hay alguna orden ( convert, pdftk, ...) o un script que puede convertir este archivo pdf con las páginas normales (una página del libro = una página en formato pdf)?

xralf
fuente
1
Aunque no es la respuesta más votada, esta realmente me sorprendió. Es simple, corto, rápido y elegante. Pensé que valía la pena mencionarlo aquí, ya que a veces somos demasiado vagos para desplazarnos hacia otras respuestas ...
Peque
Para los registros, la operación inversa (unir varias páginas) puede obtenerse desde la línea de comandos (en lugar de "imprimir en archivo") con pdfnup, desde el pdfjamconjunto de aplicaciones.
Skippy le Grand Gourou

Respuestas:

46

Aquí hay un pequeño script de Python que usa la biblioteca PyPdf que hace el trabajo perfectamente. Guárdelo en un script llamado un2up(o lo que quiera), hágalo ejecutable ( chmod +x un2up) y ejecútelo como 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)

Ignorar cualquier advertencia de desaprobación; solo los mantenedores de PyPdf deben preocuparse por eso.

Si la entrada está orientada de una manera inusual, es posible que deba usar diferentes coordenadas al truncar las páginas. Consulte ¿Por qué mi código no divide correctamente cada página en un PDF escaneado?


En caso de que sea útil, aquí está mi respuesta anterior que utiliza una combinación de dos herramientas más alguna intervención manual:

  • Pdfjam (al menos la versión 2.0), basado en el paquete pdfpages LaTeX, para recortar las páginas;
  • Pdftk , para volver a unir las mitades izquierda y derecha.

Ambas herramientas son necesarias porque, por lo que puedo decir, pdfpages no puede aplicar dos transformaciones diferentes a la misma página en una secuencia. En la llamada a pdftk, reemplace 42 por el número de páginas en el 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

En caso de que no tenga pdfjam 2.0, es suficiente tener una instalación de PDFLaTeX con el paquete pdfpages (en Ubuntu: necesita texlive-latex-recomendado Instalar texlive-latex-recomendado y quizás (en Ubuntu: texlive-fonts-recomendado Instalar texlive-fonts-recomendado ), y use el siguiente controlador archivo 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}

Luego ejecute los siguientes comandos, reemplazando 42 por el número de páginas en el archivo de entrada (que debe llamarse 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- deja de ser malvado'
fuente
La biblioteca PyPdf funciona a la perfección. Solo lo cambié un poco y lo ejecuté con python conv_pdf.py res.pdf . ¿Cómo ejecutarías tu script shebang desde la línea de comandos?
xralf
También me gustaría probar la versión con pdfjam (debido a un ligero escalado), pero después de la instalación del paquete pdfjam mi shell no reconocerá el pdfjamcomando.
xralf
@xralf: mi script de Python solo lee de la entrada estándar y escribe en la salida estándar. La versión pdfjam requiere pdfjam 2.0; es solo un pequeño contenedor alrededor de las páginas pdf, y he agregado la parte de LaTeX que genera para que pueda usarla directamente. El problema de escalado probablemente se puede resolver con pypdf, podría ser un problema de tamaño de página (puedo o no ayudarlo si proporciona más detalles sobre lo que está sucediendo y especialmente los tamaños de página involucrados).
Gilles 'SO- deja de ser malvado'
Gracias, la diferencia está en una resolución ligeramente peor, pero esto no importa. Volveré a ello cuando sepa más sobre Latex (ahora es demasiado complejo para mí y la solución es realmente buena con PyPdf).
xralf
1
@Gilles Versy script útil. Esperaba ver algo así en pdfjam, pdftk. De todos modos, algunas personas pueden querer algunas modificaciones para dividir las páginas sobre otro eje y usar un orden diferente. Esto es posible con el cambio de algunas líneas y el usoq.mediaBox.lowerRight = (w, h/2)
ony
52

Solo una adición ya que tuve problemas con el script python (y varias otras soluciones): para mí mutoolfuncionó muy bien. Es una adición simple y pequeña que se envía con el elegante mupdflector. Entonces puedes probar:

mutool poster -y 2 input.pdf output.pdf

Para divisiones horizontales, reemplace ycon x. Y, por supuesto, puede combinar los dos para obtener soluciones más complejas.

Realmente feliz de haber encontrado esto (después de años de uso diario de mupdf :)

mutoolse entrega con mupdf a partir de la versión 1.4: http://www.mupdf.com/news


Instalación mupdfy mutooldesde la fuente:

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

O vaya a la página de descargas para encontrar una versión más nueva.

martz
fuente
3
Tuve un djvu ... lo convertí en una posdata (bastante rápido), luego en un pdf (tortuga lenta), y finalmente mutool lo cortó tan rápido que pensé que no funcionaba, ¡lo había hecho!
Julien Puydt
2
Sí, también estaba muy satisfecho con la velocidad.
Martz
3
Este es el más fácil y mejor. mutoolfue hecho para esto. Además, ten cuidado -y, creo que en la mayoría de los casos lo que quieres es -x.
fiatjaf
2
Esta utilidad es muy rápida, sin embargo, tengo un problema con el orden de las páginas. El comando asigna la página derecha en la primera posición y la página izquierda en la segunda. ¿Alguien puede ayudarme con este problema?
garciparedes
16

Imagemagick puede hacerlo en un solo paso:

$ convert in.pdf -crop 50%x0 +repage out.pdf
tomas
fuente
1
Gracias. Si agrego el -density 400parámetro` tiene una calidad aún mejor.
xralf
11
Parece que convertir usa ráster como formato intermedio. Eso provoca un aspecto borroso incluso cuando el PDF original contiene objetos vectoriales.
ony
¿Alguien sabe de una manera de hacer esto sin rasterizar el contenido de la página en el camino ... o al menos para establecer una resolución más alta?
Tomislav Nakic-Alfirevic
esto tradujo textos en imágenes y creó pdf a partir de imágenes. Quizás sea bueno para las fotos pero inútil para la extracción de texto.
andrej
6

El comando Convertir de ImageMagick puede ayudarlo a recortar su archivo en 2 partes. Ver http://www.imagemagick.org/Usage/crop/

Si yo fuera usted, escribiría un script (shell) como este:

  1. Divida su archivo con pdfsam : 1 página = 1 archivo en el disco (El formato no importa. Elija uno que ImageMagick conozca. Simplemente tomaría PS o PDF.
  2. Para cada página, recorte la primera mitad y póngala en un archivo llamado $ {PageNumber} A

  3. Recorta la segunda mitad y ponla en un archivo llamado $ {PageNumber} B.

    Obtiene 1A.pdf, 1B.pdf, 2A.pdf, 2B.pdf, etc.

  4. Ahora, reúna esto nuevamente en un nuevo PDF. Hay muchos métodos para hacer esto.
tiktak
fuente
1
¿No usar ImageMagick rasteriza los archivos? Y debe explicar esa última parte en línea, especialmente en beneficio de los no francófonos en la audiencia.
Gilles 'SO- deja de ser malvado'
Porque no necesitas entender francés. Solo muestra cómo puede usar el convertidor, pdftk o ghostscript (gs) de ImageMagick solo para lograr este objetivo. Me gusta usar pdftk. "Rastering" no importa, ya que es un documento escaneado.
tiktak
6

Basado en la respuesta de Gilles y cómo encontrar el recuento de páginas PDF que escribí

#!/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

Entonces puedo correr

./split.sh my.pdf 50 1.2

donde 50 para ajustar el margen y 1.2 para la escala.

Anton Bessonov
fuente
4

Aquí hay una variación del código PyPDF publicado por Gilles. Esta función funcionará sin importar la orientación de la 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
fuente
2

La mejor solución fue mutool ver arriba:

sudo apt install mupdf-tools pdftk

la división:

mutool poster -y 2 input.pdf output.pdf

pero luego debes rotar las páginas a la izquierda:

pdftk output.pdf cat 1-endleft output rotated.pdf
Eduard Florinescu
fuente
Todavía no hay superposición ...
MUY Bélgica
1

Basado en la respuesta de Benjamin en AskUbuntu, recomendaría usar la herramienta GUI llamada gscan2pdf .

  1. Importe el archivo de escaneo PDF a gscan2pdf. Tenga en cuenta que los archivos PDF que no son de imagen pueden no funcionar. Los escaneos están bien, por lo que no tiene que preocuparse.

    ingrese la descripción de la imagen aquí

  2. Puede tomar un tiempo dependiendo del tamaño del documento. Espera hasta que se cargue.

  3. Presione Ctrl + A para seleccionar todas las páginas y luego gírelas (Ctrl + Shift + C) si es necesario.

    ingrese la descripción de la imagen aquí

  4. Vaya a Herramientas >> Limpiar . Seleccione Diseño como doble y # páginas de salida = 2 .

    ingrese la descripción de la imagen aquí

  5. Presione OK y espere hasta que termine el trabajo.

    ingrese la descripción de la imagen aquí

  6. Guarda el archivo PDF. Hecho.

Nanashi No Gombe
fuente
Probado, falló con documentos PDF complejos con una gran cantidad de imágenes.
MUY Bélgica
0

La solución de moraes no funcionó para mí. El principal problema fue el cálculo x5 y x6. Aquí se debe considerar un desplazamiento, es decir, si lowerLeft no está en (0,0)

Así que aquí hay otra variación, con adaptaciones adicionales para usar PyPDF2 y 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
fuente