web-dev-qa-db-fra.com

Fusionner plusieurs jpg en un seul pdf sous Linux

J'ai utilisé la commande suivante pour convertir et fusionner tous les fichiers jpg d'un répertoire en un seul fichier pdf.

convert *.jpg file.pdf

Les fichiers du répertoire sont numérotés de 1.jpg à 123.jpg. La conversion s'est bien passée, mais après la conversion, les pages étaient toutes mélangées. Je voulais que le pdf contienne des pages de 1.jpg à 123.jpg dans le même ordre que leur nom. J'ai également essayé avec la commande suivante:

cd 1 
FILES=$( find . -type f -name "*jpg" | cut -d/ -f 2)
mkdir temp && cd temp 
for file in $FILES; do 
    BASE=$(echo $file | sed 's/.jpg//g');
    convert ../$BASE.jpg $BASE.pdf; 
    done && 
pdftk *pdf cat output ../1.pdf && 
cd .. 
rm -rf temp

Mais toujours pas de chance. Plateforme d'exploitation Linux.

56
Harikrishnan

Le problème est dû au fait que votre Shell développe le caractère générique dans un ordre purement alphabétique et parce que les longueurs des nombres sont différentes, l'ordre sera incorrect:

$ echo *.jpg
1.jpg 10.jpg 100.jpg 101.jpg 102.jpg ...

La solution consiste à remplir les noms de fichiers avec des zéros comme requis afin qu'ils soient de la même longueur avant d'exécuter votre commande convert:

$ for i in *.jpg; do num=`expr match "$i" '\([0-9]\+\).*'`;
> padded=`printf "%03d" $num`; mv -v "$i" "${i/$num/$padded}"; done

Maintenant, les fichiers seront mis en correspondance par le caractère générique dans le bon ordre, prêts pour la commande de conversion:

$ echo *.jpg
001.jpg 002.jpg 003.jpg 004.jpg 005.jpg 006.jpg 007.jpg 008.jpg ...
16
Delan Azabani

Ou lisez simplement le manuel ls et voyez:

-v type naturel de (version) numéros dans le texte

Donc, faire ce dont nous avons besoin en une seule commande.

convert `ls -v *.jpg` foobar.pdf

Amusez-vous;) F.

92
Felix Defrance

Vous pourriez utiliser

convert '%d.jpg[1-132]' file.pdf

via https://www.imagemagick.org/script/command-line-processing.php :

Une autre méthode de référence à d'autres fichiers d'image consiste à incorporer un caractère de formatage dans le nom de fichier avec une plage de scènes. Considérez le nom de fichier image-%d.jpg[1-5]. La commande

magick image-%d.jpg[1-5] oblige ImageMagick à lire les images avec ces noms de fichiers:

image-1.jpg image-2.jpg image-3.jpg image-4.jpg image-5.jpg

Voir aussi https://www.imagemagick.org/script/convert.php

4
Lukas

Voici comment je le fais:
Première ligne convertir tous les fichiers jpg en pdf, il utilise la commande convert.
La deuxième ligne fusionne tous les fichiers pdf en un seul fichier pdf par page. Ceci utilise gs ((PostScript et PDF interprète et prévisualisateur de langue))

for i in $(find . -maxdepth 1 -name "*.jpg" -print); do convert $i ${i//jpg/pdf}; done
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=merged_file.pdf -dBATCH `find . -maxdepth 1 -name "*.pdf" -print"`
4
Martian

Toutes les réponses ci-dessus ont échoué pour moi, lorsque je voulais fusionner de nombreuses images JPEG haute résolution (à partir d'un livre numérisé).

Imagemagick a essayé de charger tous les fichiers dans la RAM, j'ai donc utilisé l'approche en deux étapes suivante:

find -iname "*.JPG" | xargs -I'{}' convert {} {}.pdf
pdfunite *.pdf merged_file.pdf

Notez qu'avec cette approche, vous pouvez également utiliser GNU parallèle pour accélérer la conversion:

find -iname "*.JPG" | parallel -I'{}' convert {} {}.pdf
2
Gregor Sturm

En mélangeant la première idée avec leur réponse, je pense que ce code peut être satisfaisant

jpgs2pdf.sh

#!/bin/bash

cd $1
FILES=$( find . -type f -name "*jpg" | cut -d/ -f 2)
mkdir temp > /dev/null
cd temp

for file in $FILES; do
 BASE=$(echo $file | sed 's/.jpg//g');
 convert ../$BASE.jpg $BASE.pdf;
done &&

pdftk `ls -v *pdf` cat output ../`basename $1`.pdf
cd ..
rm -rf temp
0
Juan Lagos