Merge multiple jpg into single pdf in Linux

Solution 1:

Or just read the ls manual and see :

-v natural sort of (version) numbers within text

So, doing what we need in single command.

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

Have fun ;) F.

Solution 2:

The problem is because your shell is expanding the wildcard in a purely alphabetical order, and because the lengths of the numbers are different, the order will be incorrect:

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

The solution is to pad the filenames with zeros as required so they're the same length before running your convert command:

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

Now the files will be matched by the wildcard in the correct order, ready for the convert command:

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

Solution 3:

You could use

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

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

Another method of referring to other image files is by embedding a formatting character in the filename with a scene range. Consider the filename image-%d.jpg[1-5]. The command

magick image-%d.jpg[1-5] causes ImageMagick to attempt to read images with these filenames:

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

See also https://www.imagemagick.org/script/convert.php

Solution 4:

All of the above answers failed for me, when I wanted to merge many high-resolution jpeg images (from a scanned book).

Imagemagick tried to load all files into RAM, I therefore used the following two-step approach:

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

Note that with this approach, you can also use GNU parallel to speed up the conversion:

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