Як об'єднати 2 файли PDF з порядком переплетення сторінок?


13

У мене є багатосторінковий друкований багатосторінковий документ для сканування за допомогою лінійного масового сканера. Отже, в результаті я отримую 2 PDF-файли: один, що містить усі непарні сторінки, а другий, що містить усі парні сторінки. Мені потрібно злити їх природним шляхом:

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)

тощо.


Просто знайдіть аналізатор PDF і зробіть сортування подібних матеріалів.
ромашка

1
Якщо Стефан не вирішить вашу проблему, ви можете спробувати модуль perl CAM::PDF, і я надаю сценарій пізніше. Чи є одна кількість файлів у форматі PDF однакова?
ромашка

Відповіді:


7

Див. pdfseparateТа pdfuniteкоманди з poppler-utils. Перші відокремлюють сторінки від кожного документа в окремі файли, а другі для об'єднання їх у потрібному порядку в новому документі.

Також зауважте, що оскільки сканери так чи інакше дають вам растрові зображення (які такі, як ваш, можна об'єднати у PDF-файли), можливо, ви можете налаштувати його для виведення зображень (png, tiff ...), а також зробити конкатенацію в PDF самостійно ImageMagick.


Це звучить як те, що мені потрібно, спробуємо ...
Іван

1
Справді. Відмінно. Простий у використанні, щоб зробити правильно те, що мені потрібно. до речі, я, звичайно, гугл перед запитанням, і рішення, які я знайшов саме такі, були значно складнішими.
Іван

Я спробував це на Ubuntu 18.04 (з корисним сценарієм нижче від @TCF), і він перетворив два ~ 5,5 Мб файли в один 197 Мбіт-файл, тому, хоча він зробив цю роботу, він не був корисним (мені потрібно було надіслати електронною поштою результат!) .
Рувім Томас,

12

pdftk має команду перетасування, яка об'єднує сторінки:

pdftk A=odd.pdf B=even.pdf shuffle A B output collated.pdf

1
Це добре працювало для мене, але з налаштуванням для повернення рівних сторінок (з огляду на те, що я сканував їх, не попередньо змінюючи порядок сторінок): pdftk A = recto.pdf B = verso.pdf перетасовувати вихід Bend-1 зіставлений. pdf
Рувім Томас

Фантастичний, спасибі - це прекрасно працює
infomaniac

2

Просто bashшвидкий знімок із використанням pdfjam:

Побудувати масив вхідних аргументів:

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

Це дозволить вам використовувати його як список вводу для pdfjoin:

 pdfjoin ${PAGES[@]} --outfile shuffled.pdf

2
Слід зазначити, що pdfjoinце скрипт для обгортки, навколо pdfjamякого є сам сценарій обгортки навколо pdfpagesпакета LaTeX (і pdflatex), тому він означає, що він приносить LaTeX як залежність.
Стефан Шазелас

1

Ви можете використовувати модуль Mix у PDFsam Basic (безкоштовно та з відкритим кодом) або зробити це в Інтернеті за допомогою функції Alternate & Mix у Sejda


1
Вручайте найкраще рішення: відкритий код, установка не потрібна. 2 кліки і зроблено;)
Натан

0

Я хотів зробити в основному те саме, і відповідь Стефана Шазеласа була дуже корисною. Я роблю це досить часто, щоб написати автоматичний сценарій Python для автоматизації роботи, використовуючи запропоновані ним команди. За замовчуванням він змінює порядок парних сторінок, але це можна придушити прапором командного рядка.

Питання якесь старе, тому я очікую, що потреби оригінального запитувача вже були задоволені. Однак можливо, що сценарій буде корисний людям, які приїдуть сюди в майбутньому, тому я розмістив його нижче.

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

0

Я наткнувся на цей скрипт bash, роблячи це, він передбачає, що ви сканували парні сторінки в зворотному порядку, але ви можете змінити це, видаливши -rв рядку приказку evenpages=($(ls "$evenbase-$key-"* | sort -r))(це рядок 46)

#!/bin/bash
# Copyright Fabien André <fabien.andre@xion345.info>
# 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

Джерело

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.