Comment fusionner 2 fichiers PDF avec l'ordre d'entrelacement des pages?

13

J'ai un document multipage imprimé recto verso à numériser avec un scanner linéaire en vrac. Donc, comme résultat, j'obtiens 2 fichiers PDF: un contenant toutes les pages impaires et le second contenant toutes les pages paires. Je dois les fusionner de manière naturelle:

1. <- 1.1. (odd.pdf page 1 to result.pdf page 1)
2. <- 2.1. (even.pdf page 1 to result.pdf page 2)
3. <- 1.2. (odd.pdf page 2 to result.pdf page 3)
4. <- 2.2. (even.pdf page 2 to result.pdf page 4)

etc.

Ivan
la source
Il suffit de trouver un analyseur PDF et de faire un tri de fusion comme des trucs.
marguerite du
1
Si Stéphane ne résout pas votre problème, vous pouvez essayer le module perl CAM::PDF, je vous donnerai un script plus tard. Les deux pdf ont-ils le même nombre de pages?
marguerite

Réponses:

7

Voir les commandes pdfseparateet pdfunitede poppler-utils. Le premier pour séparer les pages de chaque document dans des fichiers individuels et le second pour les fusionner dans l'ordre souhaité dans un nouveau document.

Notez également que puisque les scanners vous donnent quand même des images raster (que certains comme le vôtre peuvent concaténer dans des fichiers PDF), vous pouvez peut-être le configurer pour produire des images (png, tiff ...) à la place, et faire la concaténation dans un PDF vous-même avec ImageMagick.

Stéphane Chazelas
la source
Cela ressemble à ce dont j'ai besoin, essayons ...
Ivan
1
En effet. Excellent. Simple à utiliser pour faire ce dont j'ai besoin. Soit dit en passant, j'ai bien sûr fait une recherche sur Google avant de demander et les solutions que j'ai trouvées exactement les mêmes étaient considérablement plus complexes.
Ivan
J'ai essayé cela sur Ubuntu 18.04 (avec le script utile ci-dessous de @TCF) et il a transformé deux fichiers de ~ 5,5 Mo en un fichier de 197 Mo, donc pendant qu'il faisait le travail, il n'était pas utilisable (j'avais besoin d'envoyer le résultat par e-mail!) .
Reuben Thomas
12

pdftk a une commande shuffle qui rassemble les pages:

pdftk A=odd.pdf B=even.pdf shuffle A B output collated.pdf
djao
la source
1
Cela a bien fonctionné pour moi, mais avec un ajustement pour inverser les pages paires (étant donné que je les ai numérisées sans inverser d'abord l'ordre des pages): pdftk A = recto.pdf B = verso.pdf shuffle Une sortie Bend-1 collationnée. pdf
Reuben Thomas
Fantastique, merci - cela fonctionne parfaitement
infomaniac
2

Juste un bashcoup rapide en utilisant pdfjam:

Créez un tableau d'arguments d'entrée:

for k in $(seq 1 ${N_PAGES}); do
    PAGES+=(odd.pdf);
    PAGES+=($k);
    PAGES+=(even.pdf);
    PAGES+=($k);
done

Cela devrait vous permettre de l'utiliser comme liste d'entrée pour pdfjoin:

 pdfjoin ${PAGES[@]} --outfile shuffled.pdf
fheub
la source
2
Il convient de noter qu'il pdfjoins'agit d'un script d'encapsulation pdfjamqui est lui-même un script d'encapsulation autour du pdfpagespackage LaTeX (et de pdflatex), ce qui signifie qu'il apporte LaTeX en tant que dépendance.
Stéphane Chazelas
1

Vous pouvez utiliser le module Mix dans PDFsam Basic (gratuit et open source) ou le faire en ligne en utilisant la fonction Alternate & Mix dans Sejda

Andrea Vacondio
la source
1
De loin la meilleure solution: open source, aucune installation requise. 2 clics et c'est fait;)
nathan
0

Je cherchais à faire essentiellement la même chose, et la réponse de Stéphane Chazelas a été très utile. Je le fais assez souvent pour que j'écrive un simple script Python pour automatiser les choses, en utilisant les commandes qu'il a suggérées. Par défaut, il inverse l'ordre des pages paires, mais cela peut être supprimé avec un indicateur de ligne de commande.

La question est un peu ancienne, je suppose donc que les besoins du demandeur d'origine ont déjà été satisfaits. Cependant, il est possible que le script soit utile aux personnes qui arriveront ici à l'avenir, je l'ai donc placé ci-dessous.

#!/usr/bin/python
"""A simple script to merge two PDFs."""

import argparse
from os import listdir
from os.path import join as opjoin
import shutil
from subprocess import check_call, CalledProcessError
import tempfile

SEPARATE = 'pdfseparate %s %s'
MERGE = 'pdfunite %s %s'

def my_exec(command):
    """Execute a command from a shell, ignoring errors."""
    try:
        check_call(command, shell=True)
    except CalledProcessError:
        pass

def run(odd, even, out, reverse_odd=False, reverse_even=True):
    """Interleave odd and even pages from two PDF files."""
    folder = tempfile.mkdtemp()
    my_exec(SEPARATE % (odd, opjoin(folder, 'odd%d.pdf')))
    my_exec(SEPARATE % (even, opjoin(folder, 'even%d.pdf')))
    odd_files = []
    even_files = []
    for curr_file in listdir(folder):
        filepath = opjoin(folder, curr_file)
        if curr_file.startswith('odd'):
            odd_files.append((filepath, int(curr_file[3:-4])))
        elif curr_file.startswith('even'):
            even_files.append((filepath, int(curr_file[4:-4])))
    func = lambda x: x[1]
    odd_files.sort(key=func, reverse=reverse_odd)
    even_files.sort(key=func, reverse=reverse_even)
    parts = []
    for line in zip(odd_files, even_files):
        parts.append(line[0][0])
        parts.append(line[1][0])
    my_exec(MERGE % (' '.join(parts), out))
    shutil.rmtree(folder)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Merge two PDF files.')
    parser.add_argument('odd_pages', help='PDF containing the odd pages.')
    parser.add_argument('even_pages', help='PDF containing the even pages.')
    parser.add_argument('output_file', help='The target output file.')
    parser.add_argument('--reverse-odd', action='store_true', 
                        help='Insert the odd pages in reverse order.')
    parser.add_argument('--no-reverse-even', action='store_true',
                        help='Suppress reversal of the even pages.')
    args = parser.parse_args()
    run(args.odd_pages, args.even_pages, args.output_file,
        args.reverse_odd, not args.no_reverse_even)
TCF
la source
0

Je suis tombé sur ce script bash en faisant cela, il suppose que vous avez numérisé les pages paires dans l'ordre inverse, mais vous pouvez changer cela en supprimant le -rdans la ligne en disant evenpages=($(ls "$evenbase-$key-"* | sort -r))(c'est la ligne 46)

#!/bin/bash
# Copyright Fabien André <[email protected]>
# Distributed under the MIT license
# This script interleaves pages from two distinct PDF files and produces an
# output PDF file. The odd pages are taken from a first PDF file and the even
# pages are taken from a second PDF file passed respectively as first and second
# argument.
# The first two pages of the output file are the first page of the
# odd pages PDF file and the *last* page of the even pages PDF file. The two
# following pages are the second page of the odd pages PDF file and the
# second to last page of the even pages PDF file and so on.
#
# This is useful if you have two-sided documents scanned each side on a
# different file as it can happen when using a one-sided Automatic Document
# Feeder (ADF)
#
# It does a similar job to :
# https://github.com/weltonrodrigo/pdfapi2/blob/46434ab3f108902db2bc49bcf06f66544688f553/contrib/pdf-interleave.pl
# but only requires bash (> 4.0) and poppler utils.
# Print usage/help message
function usage {
echo "Usage: $0 <PDF-even-pages-file> <PDF-odd-pages-file>"
exit 1
}
# Add leading zeros to pad numbers in filenames matching the pattern
# $prefix$number.pdf. This allows filenames to be easily sorted using
# sort.
# $1 : The prefix of the filenames to consider
function add_leading_zero {
prefix=$1
baseprefix=$(basename $prefix | sed -e 's/[]\/()$*.^|[]/\\&/g')
dirprefix=$(dirname $prefix)
for filename in "$prefix"*".pdf"
do
base=$(basename "$filename")
index=$(echo "$base" | sed -rn "s/$baseprefix([0-9]+).pdf$/\1/p")
newbase=$(printf "$baseprefix%04d.pdf" $index)
mv $filename "$dirprefix/$newbase"
done
}
# Interleave pages from two distinct PDF files and produce an output PDF file.
# Note that the pages from the even pages file (second file) will be used in
# the reverse order (last page first).
# $1 : Odd pages filename
# $2 : Odd pages filename with extension removed
# $3 : Even pages filename
# $4 : Even pages filename with extension removed
# $5 : Unique key used for temporary files
# $6 : Output file
function pdfinterleave {
oddfile=$1
oddbase=$2
evenfile=$3
evenbase=$4
key=$5
outfile=$6
# Odd pages
pdfseparate $oddfile "$oddbase-$key-%d.pdf"
add_leading_zero "$oddbase-$key-"
oddpages=($(ls "$oddbase-$key-"* | sort))
# Even pages
pdfseparate $evenfile "$evenbase-$key-%d.pdf"
add_leading_zero "$evenbase-$key-"
evenpages=($(ls "$evenbase-$key-"* | sort -r))
# Interleave pages
pages=()
for((i=0;i<${#oddpages[@]};i++))
do
pages+=(${oddpages[i]})
pages+=(${evenpages[i]})
done
pdfunite ${pages[@]} "$outfile"
rm ${oddpages[@]}
rm ${evenpages[@]}
}
if [ $# -lt 2 ]
then
usage
fi
if [ $1 == $2 ]
then
echo "Odd pages file and even pages file must be different." >&2
exit 1
fi
if ! hash pdfunite 2>/dev/null || ! hash pdfseparate 2>/dev/null
then
echo "This script requires pdfunite and pdfseparate from poppler utils" \
"to be in the PATH. On Debian based systems, they are found in the" \
"poppler-utils package"
exit 1
fi
oddbase=${1%.*}
evenbase=${2%.*}
odddir=$(dirname $oddbase)
oddfile=$(basename $oddbase)
evenfile=$(basename $evenbase)
outfile="$odddir/$oddfile-$evenfile-interleaved.pdf"
key=$(tr -dc "[:alpha:]" < /dev/urandom | head -c 8)
if [ -e $outfile ]
then
echo "Output file $outfile already exists" >&2
exit 1
fi
pdfinterleave $1 $oddbase $2 $evenbase $key $outfile
# SO - Bash command that prints a message on stderr
# http://stackoverflow.com/questions/2643165/bash-command-that-prints-a-message-on-stderr
# SO - Check if a program exists from a bash script
# http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script
# SO - How to debug a bash script?
# http://stackoverflow.com/questions/951336/how-to-debug-a-bash-script
# SO - Escape a string for sed search pattern
# http://stackoverflow.com/questions/407523/escape-a-string-for-sed-search-pattern

La source

switch87
la source