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.