Skip to content

Instantly share code, notes, and snippets.

@dreness
Last active April 1, 2021 02:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dreness/1ebb2a9b3175ccdaa1fd109f84e30243 to your computer and use it in GitHub Desktop.
Save dreness/1ebb2a9b3175ccdaa1fd109f84e30243 to your computer and use it in GitHub Desktop.
Batch convert SVGs to PDF using Inkscape
#!/bin/zsh
IMAGE_DIR=$1
INK="/Applications/Inkscape.app/Contents/MacOS/inkscape"
SCRIPT="inkscript"
COUNT=0
# If gdate is available (brew install coreutils), we can show precise timing info
type -a gdate &> /dev/null && HAS_GDATE=1
# Make a script for Inkscape's --shell mode
makeInkScript() {
for file in *.svg ; do
echo << EOF >> ${SCRIPT}
file-open:${file}
export-filename:${file}.pdf
export-type:pdf
export-do
file-close:${file}
EOF
COUNT=$((COUNT += 1))
done
echo "Batching ${COUNT} images..."
}
doAllThatStuff() {
cat ${SCRIPT} | ${INK} --shell &> /dev/null
}
pushd $IMAGE_DIR
[ ! -z $HAS_GDATE ] && INK_START=$(gdate +%s.%N)
makeInkScript
[ ! -z $HAS_GDATE ] && INK_END=$(gdate +%s.%N)
if [ ! -z $HAS_GDATE ] ; then
echo -n "Time required to compose Inkscape script: "
echo $((INK_END - INK_START))
fi
[ ! -z $HAS_GDATE ] && CONVERT_START=$(gdate +%s.%N)
doAllThatStuff > /dev/null
[ ! -z $HAS_GDATE ] && CONVERT_END=$(gdate +%s.%N)
if [ ! -z $HAS_GDATE ] ; then
echo -n "Time required to convert images: "
echo $((CONVERT_END - CONVERT_START))
fi
popd
@dreness
Copy link
Author

dreness commented Mar 26, 2021

"Ok whatever, but is the timing info really all that interesting?", you may wonder...

That might depend on your platform. Here in macOS, fork / exec is still painfully slow. So slow, in fact, that my initial version of this script took longer to compose the Inkscape batch file than to actually do the image conversions!

Batching 2383 images...
Time required to compose Inkscape script: 5.8204770088195801
Time required to convert images: 4.8342380523681641

This is because cat is an external command, which runs once for each image to convert. Meanwhile, the whole point of using Inkscape's --shell mode is to allow Inkscape to do all the work in the batch file in a single process life cycle. After making the obvious change to use the shell built-in echo instead of cat:

14c14
<         cat << EOF >> ${SCRIPT}
---
>         echo << EOF >> ${SCRIPT}

... now we're in business:

Batching 2383 images...
Time required to compose Inkscape script: 0.71118903160095215
Time required to convert images: 5.1587259769439697

@dreness
Copy link
Author

dreness commented Mar 26, 2021

Also, be aware that I'm aware that I spent far more time composing this gist and associated comments than I gained with the faster implementation ;)

@beren12
Copy link

beren12 commented Mar 26, 2021

👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment