2012 0003 0024

QR Codes En Masse

For the upcoming POSSCON here in Columbia, we had need of QR codes for the brochure. Lots of them. And while there are some great online resources, I wanted to create QR codes in batch.

Of course, the online services could be batch processed with a dose of curl magic, but there is a more UNIX way: libqrencode.

Creating a discrete QR code image is straightforward with the qrencode command:

qrencode -o output.png -s 50 "https://www.malloc47.com"

The -s parameter controls the size of the QR “dots” and therefore the output resolution.

This is great if you don’t need a vectorized format, but for print-quality work where you may not know the eventual DPI, having vectorized output (e.g. eps, and svg) is preferable.

Again, the vast repositories of libre software come to the rescue here: potrace is designed for exactly this. Annoyingly, it only handles bitmap (or the easy-to-generate pnm) format, so a little imagemagick will take care of this:

convert output.png output.bmp

Now we can convert to a vector format easily:

potrace -e -o output.eps output.bmp # -e is for EPS
potrace -s -o output.svg output.bmp # -s is for SVG

We can wrap it all up into a nice (bash) script:

#!/bin/bash
set -e
qrencode -o $1.png -s 50 "$2"
convert $1.png $1.bmp
potrace -e -o $1.eps $1.bmp
rm $1.png $1.bmp

which takes a file name prefix and a string to be encoded. To generate a large set of QR codes with this script, simply create a file with file prefix-URL(or whatever data is to be encoded) pairs, each on a separate line,

google https://www.google.com
amazon https://www.amazon.com
reddit https://www.reddit.com
....

and then loop over this file, line-by-line:

while read line ; do ./create-qr-code.sh $line ; done < list.text

which conveniently gives us google.eps, amazon.eps, and reddit.eps files for their respective URLs.

If there is uncertainty that your URLs are good (i.e. don’t kick back 404s), then you can augment the above script with this nice curl snippet (courtesy of this post on SO):

#!/bin/bash
set -e
curl -s --head $2 | head -n 1 | grep "HTTP/1.[01] [23].." > /dev/null
if [ $? -eq 0 ] ; then
    qrencode -o $1.png -s 50 "$2"
    convert $1.png $1.bmp
    potrace -e -o $1.eps $1.bmp
    rm $1.png $1.bmp
else
    echo "URL error: $2" 1>&2
fi

This will let you know which URLs don’t come back with clean headers so you can give them further attention. It won’t capture everything that might go wrong, but it does give you a programmatic way to verify that all is well.

Incidentally, all the tools used here can be installed on Arch with

pacman -S qrencode potrace imagemagick curl

Not exactly the prettiest shell glue, but it certainly beats slowly copy & pasting in and out of a browser.