Fork me on GitHub

Project Notes

QR Codes

Generating QR codes with python, as images and as C header files for embedded applications.


A quick test of the qrcode Python library for generating QR codes, and exploring various output formats.

NB: these tests were performed with Python 3.7.4

QR Code Basics

QR code is the trademark for a type of matrix barcode first designed in 1994 for the automotive industry in Japan. Since, of course, it has been predominantly used for smartphone quick-links.

The amount of data that can be stored in the QR code symbol depends on:

  • datatype (mode, or input character set)
  • version (1, …, 40, indicating the overall dimensions of the symbol, i.e. 4 × version number + 17 dots on each side)
  • error correction level.

Error corrections:

  • L (Low) - 7% of codewords can be restored
  • M (Medium) - 15% of codewords can be restored
  • Q (Quartile) - 25% of codewords can be restored
  • H (High) - 30% of codewords can be restored


This example uses the qrcode python client, which depends on pillow. Install with pip:

$ pip install -r requirements.txt

Command Line Test

The qrcode library has a command line interface invoked with qr:

$ qr --help
Usage: qr - Convert stdin (or the first argument) to a QR Code.

When stdout is a tty the QR Code is printed to the terminal and when stdout is
a pipe to a file an image is written. The default image format is PNG.

  --version             show program's version number and exit
  -h, --help            show this help message and exit
  --factory=FACTORY     Full python path to the image factory class to create
                        the image with. You can use the following shortcuts to
                        the built-in image factory classes: pil, pymaging,
                        svg, svg-fragment, svg-path.
  --optimize=OPTIMIZE   Optimize the data by looking for chunks of at least
                        this many characters that could use a more efficient
                        encoding method. Use 0 to turn off chunk optimization.
                        The error correction level to use. Choices are L (7%),
                        M (15%, default), Q (25%), and H (30%).

Generating a QR code for a website:

qr "" > leap.png

Resulting image:


Programmatic Generation

The simple script demonstrates generation in code. It accepts a format parameter to dictate the output file format. The output is streamed to stdout, so whould be redriected to a file for storage:

$ ./ -m "qr to png" -f png > assets/test.png
$ ./ -m "qr to gif" -f gif > assets/test.gif
$ ./ -m "qr to bmp" -f bmp > assets/test.bmp

Resulting images:

png gif bmp
png gif bmp

Generating for Embedded

A c formatter provides a simple conversion to an Arduino-compatible C datastruture that may be included in embedded programs. The code was inspired by the tobitmap implementation from PIL

$ ./ -m '' -f c -b 0 > assets/leap.h

The -b 0 parameter indicates generate with no border boxes (optional).

This generates an array of bytes in a header file structure, ready for inclusion in an Arduino sketch:

#pragma once

// Original QR code details
// * Version : 2
// * Error correction : 0
// * Box size (pixels) : 8
// * Border size (boxes) : 0
// * Message :

#define qrcode_width  200
#define qrcode_height  200

static const uint8_t PROGMEM qrcode_data[] = {
  // ... etc ...

Credits and References

About LCK#101 pythonC
Project Source on GitHub Return to the Project Catalog

This page is a web-friendly rendering of my project notes shared in the LittleCodingKata GitHub repository.

LittleCodingKata is my collection of programming exercises, research and code toys broadly spanning things that relate to programming and software development (languages, frameworks and tools).

These range from the trivial to the complex and serious. Many are inspired by existing work and I'll note credits and references where applicable. The focus is quite scattered, as I variously work on things new and important in the moment, or go back to revisit things from the past.

This is primarily a personal collection for my own edification and learning, but anyone who stumbles by is welcome to borrow, steal or reference the work here. And if you spot errors or issues I'd really appreciate some feedback - create an issue, send me an email or even send a pull-request.