it-swarm.it

Pagine divise in pdf

Ho un file pdf scansionato che ha scansionato due pagine su una pagina virtuale (pagina in file pdf).

La risoluzione è di buona qualità. Il problema è che devo ingrandire durante la lettura e trascinare da sinistra a destra.
Esiste un comando (convert, pdftk, ...) o script che può convertire questo file pdf con pagine normali (una pagina dal libro = una pagina nel file pdf )?

72
xralf

Ecco un piccolo Python che utilizza libreria PyPdf che svolge il lavoro in modo ordinato. Salvalo in uno script chiamato un2up (o qualunque cosa ti piaccia), rendilo eseguibile (chmod +x un2up) ed eseguilo come 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)

Ignora eventuali avvisi di ammortamento; solo i manutentori di PyPdf devono preoccuparsene.

Se l'input è orientato in modo insolito, potrebbe essere necessario utilizzare coordinate diverse quando si troncano le pagine. Vedi Perché il mio codice non suddivide correttamente ogni pagina in un pdf scansionato?


Nel caso sia utile, ecco la mia risposta precedente che utilizza una combinazione di due strumenti più un intervento manuale:

  • Pdfjam (almeno versione 2.0), basato sul pacchetto pdfpages LaTeX, per ritagliare le pagine;
  • Pdftk , per rimettere insieme le metà sinistra e destra.

Entrambi gli strumenti sono necessari perché, per quanto ne so, pdfpages non è in grado di applicare due diverse trasformazioni alla stessa pagina in un flusso. Nella chiamata a pdftk, sostituisci 42 con il numero di pagine nel documento di input (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

Nel caso in cui non si abbia pdfjam 2.0, è sufficiente disporre di un'installazione PDFLaTeX con il pacchetto pdfpages (su Ubuntu: è necessario raccomandato da texlive-latexInstall texlive-latex-recommended e forse (su Ubuntu: texlive-fonts-recommendedInstall texlive-fonts-recommended ) e utilizza il seguente file del driver 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}

Quindi esegui i seguenti comandi, sostituendo 42 con il numero di pagine nel file di input (che deve essere chiamato 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

Solo un'aggiunta poiché ho avuto problemi con lo python (e diverse altre soluzioni): per me mutool ha funzionato alla grande. È un'aggiunta semplice e piccola fornita con l'elegante mupdf reader. Quindi puoi provare:

mutool poster -y 2 input.pdf output.pdf

Per divisioni orizzontali, sostituire y con x. E ovviamente puoi combinare le due soluzioni più complesse.

Sono davvero felice di averlo trovato (dopo anni di utilizzo quotidiano di mupdf :)

mutool viene spedito con mupdf a partire dalla versione 1.4: http://www.mupdf.com/news


Installazione di mupdf e mutool dall'origine:

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

Oppure vai alla pagina dei download per trovare una versione più recente.

60
martz

Imagemagick può farlo in un solo passaggio:

$ convert in.pdf -crop 50%x0 +repage out.pdf
18
tomas

Sulla base della risposta di Gilles e come trovare PDF conteggio pagine ho scritto

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

Quindi posso correre

./split.sh my.pdf 50 1.2

dove 50 per regolare il margine e 1,2 per la scala.

6
Anton Bessonov

Il comando Converti di ImageMagick può aiutarti a ritagliare il tuo file in 2 parti. Vedi http://www.imagemagick.org/Usage/crop/

Se fossi in te, scriverei uno script (Shell) come questo:

  1. Dividi il tuo file con pdfsam : 1 page = 1 file su disco (il formato non ha importanza. Scegli uno che ImageMagick conosce. Vorrei solo prendere PS o PDF.
  2. Per ogni pagina, ritaglia la prima metà e inseriscilo in un file chiamato $ {PageNumber} A

  3. Ritaglia la seconda metà e inseriscila in un file chiamato $ {PageNumber} B.

    Ottieni 1A.pdf, 1B.pdf, 2A.pdf, 2B.pdf, ecc.

  4. Ora, assembla di nuovo in un nuovo PDF. Esistono molti metodi per farlo.
6
tiktak

Ecco una variante del codice PyPDF pubblicato da Gilles. Questa funzione funzionerà indipendentemente dall'orientamento della pagina:

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()
4
moraes

La soluzione migliore era mutool, vedi sopra:

Sudo apt install mupdf-tools pdftk

la divisione:

mutool poster -y 2 input.pdf output.pdf

ma poi devi ruotare le pagine a sinistra:

pdftk output.pdf cat 1-endleft output rotated.pdf
3

moraes soluzione non ha funzionato per me. Il problema principale era il calcolo x5 e x6. In questo caso è necessario considerare un offset, ovvero se lowerLeft non è su (0,0)

Quindi ecco un'altra variante, con adattamenti aggiuntivi per usare 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])
1
vbar

Sulla base di risposta di Benjamin su AskUbuntu, consiglierei di usare lo strumento GUI chiamato gscan2pdf .

  1. Importa il PDF scansiona il file in gscan2pdf. Nota che non-image PDF i file potrebbero non funzionare. Le scansioni vanno bene, quindi non devi preoccuparti.

    enter image description here

  2. Potrebbe volerci un po 'di tempo a seconda delle dimensioni del documento. Aspetta che si carichi.

  3. Premere Ctrl + A per selezionare tutte le pagine e quindi ruotare (Ctrl + Maiusc + C) se necessario.

    enter image description here

  4. Vai a Strumenti >> Pulizia . Seleziona Layout come doppio e # pagine di output = 2 .

    enter image description here

  5. Premi [~ # ~] ok [~ # ~] e attendi il completamento del lavoro.

    enter image description here

  6. Salva il file PDF. Fatto.

1