1

I need to generate several thousand qr codes of simple IDs (1234, 1235, 1236, ...) and want to be able to also make them human readable. qrencode is a really cool tool to generate qr-codes, BUT no way to add a subtitle there.

Any ideas?

muru
  • 69,900
  • 13
  • 192
  • 292
Frischling
  • 133
  • 4

3 Answers3

0

Imagemagics convert to the rescue:

  1. generate QR Code with qrencode (output PNG, SVG doesn't work with convert, I think)
  2. generate png image from string with convert
  3. append the images with convert

Here the script for this:

for i in $(cat ../input.csv); do 
  qrencode $i -t png -l H -s 10 -o $i.q.png;
  convert -size 290x40 xc:white -pointsize 34 -gravity center -font /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf -draw "text 0,0 '$i'" $i.s.png; 
 convert -append $i.q.png $i.s.png $i.png; rm $i.q.png; rm $i.s.png; 
 echo $i; 
done;

DejaVuSansMono.ttf has dots in the zeros, which makes it well readable, there might be others. 1 and small L and the usual suspects are also well discernible.

Frischling
  • 133
  • 4
0

Create an image with the text and append that to the image:

#!/bin/bash

txt="$1"
qrencode -o "$txt".png "$txt"

convert  -pointsize 36 "label:$txt" "$txt.gif"
convert -append "$txt".png "$txt.gif" "$txt.total.gif"
Ljm Dullaart
  • 4,142
  • 11
  • 26
  • Nice! If I do this with eps output format, I get 2 lines of $txt - do you know that problem? (I know it wasn't in the question...) – Frischling Jun 18 '21 at 12:27
  • I encountered some issues with `convert` and eps before; it kept printing the filename in the image. I had to go via pnm to prevent it from happening; this was the line in my script then. `convert "$fromfile" pnm:- | convert -density 300 - out.eps` Don't know if that is your issue though. – Ljm Dullaart Jun 18 '21 at 12:54
0

If you want to keep the svg format, it seems it is not that difficult to edit the xml to add a new <text> element to the end of the file. I don't know svg well enough to do this in some standard way, but looking at how the file looks when you use an svg editor to add a text line, the following awk script might suffice for the example you gave.

i=1234
qrencode "$i" -t svg -l H -s 10 -o "$i.q.svg.orig"
awk <"$i.q.svg.orig" >"$i.q.svg" -v txt="$i" '
/<svg /{ match($0,"height=\"([0-9.]+)",grp)
    ht = grp[1]*1.1
    ht = "height=\"" ht
    sub("height=\"([0-9.]+)",ht,$0)
    match($0,"viewBox=\"0 0 ([0-9]+) ([0-9]+)",grp)
    vb = int(grp[2]*1.1+.5)
    x = int(grp[1]/2+.5)
    y = grp[2]+1
    vb = "viewBox=\"0 0 " grp[1] " " vb
    sub("viewBox=\"0 0 ([0-9]+) ([0-9]+)",vb,$0)
}
/<rect x="0" /{
    match($0,"height=\"([0-9.]+)",grp)
    ht = int(grp[1]*1.1+.5)
    ht = "height=\"" ht
    sub("height=\"([0-9.]+)",ht,$0)
}
/<\/svg>/{
    printf "  <text font-family=\"Helvetica, sans-serif\" font-size=\"6\" stroke-width=\"0\" text-anchor=\"middle\" x=\"%d\" y=\"%d\" xml:space=\"preserve\">%s</text>",x,y,txt
}
{print}
'

This is more complex than really necessary, in order to be a little more generic.

It takes the initial <svg width="10.23cm" height="10.23cm" viewBox="0 0 29 29" ... and scales up the height and 4th viewBox values by 10% so it becomes <svg width="10.23cm" height="11.23cm" viewBox="0 0 29 33" ....

It then takes the background white rectangle and grows the height similarly from <rect ... height="29" to <rect ... height="33".

Finally, it then adds a <text...> line before the end, using as x and y positions the values found from the viewBox. The text-anchor="middle" centers the text on this coordinate.

meuh
  • 49,672
  • 2
  • 52
  • 114