How to batch convert an image to a PDF?

I want to batch convert images (jpg, png, etc.) to PDF. Converting them directly to PDF is easy with:

convert in.jpg out.pdf

However I need some more options, such as setting the output page size, margins and rotation between landscape and portrait format. After some trial and error I have come up with:

convert -rotate "90>" -page A4+0+0  -gravity center in.jpg  out.pdf

This centers the image on an A4 page and automatically rotates between landscape and portrait, however it only works with small images below 595x842. Larger images break, as 595x842 seems to be the resolution in pixel that is assigned to an A4 page. Reading around on the net, -density option might be a potential solution to increase the pixel count on an A4 page, but I couldn't make it work.

Solutions outside of Imagemagick are of course welcome as well.


Solution 1:

One workaround is to split the image generation and the PDF conversion. First convert the images via convert to A4@300dpi (i.e. 3508x2479), then use sam2p to convert them to PDF and then use sam2p_pdf_scale to convert them to A4.

convert -rotate "90>" -scale 3508x2479 -border 64x64 -bordercolor white in.png out.png
sam2p out.png out.pdf
sam2p_pdf_scale 595 842 out.pdf

Edit: A more complete script:

#!/bin/sh

A4_WIDTH=2479
A4_HEIGHT=3508

H_MARGIN=64
V_MARGIN=64
WIDTH=$((${A4_WIDTH} - ${H_MARGIN} * 2))
HEIGHT=$((${A4_HEIGHT} - ${V_MARGIN} * 2))

for i in "$@"; do
    TMP="/tmp/$(uuidgen).png"
    echo "$i"
    convert \
        -rotate "90>" \
        -scale "${WIDTH}x${HEIGHT}" \
        -border "${H_MARGIN}x${V_MARGIN}" -bordercolor white \
        -gravity center \
        -extent "${A4_WIDTH}x${A4_HEIGHT}" \
        -gravity center \
        -font helvetica -pointsize 80 \
        -fill white -draw \
        "push graphic-context
         translate $((${A4_WIDTH}/2 - 160)), 0
         rotate 90
         text -2,-2 '$i'
         text -2,2 '$i'
         text 2,-2 '$i'
         text 2,2 '$i'
         pop graphic-context
    " \
        -fill black -draw \
        "push graphic-context
         translate $((${A4_WIDTH}/2 - 160)), 0
         rotate 90
         text 0,0 '$i'
         pop graphic-context
    " \
        "$i" "$TMP"
    sam2p "$TMP" "${i}.pdf"
    sam2p_pdf_scale 595 842 "${i}.pdf"
done

# EOF #

Solution 2:

A bit cleaner than the other answer:

ls *.jpg | sed -r 's/(.*)\.(\w{3,4})/\1.\2 \1.pdf/' | xargs -n2 sam2p 2>&1 | grep OutputFile | perl -pe 's/.*: //' | xargs pdfjoin --outfile out.pdf

See it in action at http://convertjpgpdf.net.