How to Generate and Decode QR Codes in Python

How to Generate and Decode QR Codes in Python

How to Generate and Decode QR Codes in Python

  • by admin
  • Programming

By reading this piece, you will learn to generate your own QR code and decode QR codes from an image. At the end of this tutorial, you should be able to integrate QR codes functionality into your own Python application. For your information, a QR code is:

“…a two-dimensional pictographic code used for its fast readability and comparatively large storage capacity. The code consists of black modules arranged in a square pattern on a white background. The information encoded can be made up of any kind of data (e.g., binary, alphanumeric, or Kanji symbols)”.

There is a big difference between QR codes and bar codes. Bar codes only hold information in the horizontal direction; a QR code holds information in both horizontal and vertical directions. As a result, a QR code contains a lot more information compared to a barcode.

There are four sections in this tutorial.

  1. Setup
  2. Generate QR code
  3. Decode QR code
  4. Conclusion

Let’s proceed to the next section and start installing the necessary modules


1. Setup

It is highly recommended to create a virtual environment before you continue with the installation. We will be using the following Python packages for this tutorial:

  • python-qrcode — Python QR code image generator. Standard installation includes pillow as well for generating images.
  • opencv-python — Open-source library for computer vision, machine learning, and image processing. It comes with built-in QRCodeDetector class, which helps to decode QR codes.

Installation is pretty straight forward via pip install. Run the following command to install python-qrcode and pillow.

pip install qrcode[pil]

Once you are done, continue installing OpenCV-Python with the following command:

pip install opencv-python

If you intend to detect multiple QR codes in a single image, make sure that the opencv-python version is at least 4.3.0. Older versions do not come with the multi detection functionalities.

Let’s move on to the next section and start writing Python code.


2. Generate QR Code

Import

Add the following import declaration at the top of your Python file.

import qrcode
from PIL import Image

Basic example

For basic usage, you can simply run the make() function to generate a QR Code based on your input text:

img = qrcode.make('Your input text')

Advanced usage

You can utilize the QRCode class, which comes with a lot more controls and properties.

qr = qrcode.QRCode(
    version=1,
    error_correction=qrcode.constants.ERROR_CORRECT_H,
    box_size=10,
    border=4,
)
  • version — Accepts an integer from 1 to 40 which controls the size of the QR Code. The smallest version 1 has a dimension of 21 x 21.
  • box_size — Determines the number of pixels for each box of the QR code.
  • border — Determines the thickness of the border of the boxes. The default value is 4, which is the minimum size.
  • error_correction — Controls the error correction used. It will be further explained in the next paragraph.

Error correction constant

Error correction helps to improve the detection even when the image is disfigured or there is an overlay image on top of the QR Code. There are four constants available for error_correction:

  • ERROR_CORRECT_L — About 7% or fewer errors can be corrected.
  • ERROR_CORRECT_M — About 15% or fewer errors can be corrected. This is the default value.
  • ERROR_CORRECT_Q — About 25% or fewer errors can be corrected.
  • ERROR_CORRECT_H — About 30% or fewer errors can be corrected.

Save as image file

The next step is to call the add_data() function. Pass in the input text of your choice. Continue by appending the following code to generate a QR code with a white background and black fill.

qr.add_data('https://www.learningcrux.com/)
qr.make(fit=True)img = qr.make_image(fill_color="black", back_color="white").convert('RGB')

You can save it in as an image file as follow:

img.save("sample.png")

You should see a newly generated QR code, such as the one below:

Image for post

Overlay an image on a QR Code

You might notice that some of the QR codes contain an overlay image on top of it. This helps to promote your brand and prevent confusion with the other QR codes. If you intend to do so, make sure to use the best error_correction constant to prevent issues with decoding it wrongly.

You can utilize a pillow to add an overlay image on top of your QR code. Let’s call the image constructor to open up an image. The thumbnail() function helps to resize the image. You should downsize it to a smaller resolution to prevent it from blocking the entire QR code.

logo_display = Image.open('profile.png')
logo_display.thumbnail((60, 60))

Call the following code to calculate the center position and overlay the thumbnail on top of the QR code via the paste() function.

logo_pos = ((img.size[0] - logo_display.size[0]) // 2, (img.size[1] - logo_display.size[1]) // 2)img.paste(logo_display, logo_pos)

Save it via the save() function, just like what we have done earlier.

img.save("sample2.png")

Here is an example of how it will look:

Image for post


3. Decode QR Code

In this section, I am going to decode the QR codes that I have generated earlier. I recommend that you create a new Python file for this.

Single QR code

Add the following import statement.

import cv2 as cv

The QRCodeDetector provides us with the following functions:

  • detect — Detects QR code in image and returns the quadrangle containing the code.
  • decode — Decodes QR code in the image once it’s found by the detect() method. Returns UTF8-encoded output string or an empty string if the code cannot be decoded.
  • detectAndDecode — Both detect and decode QR code.

To keep things short and simple, I am using detectAndDecode() function for this tutorial.

im = cv.imread('sample.png')
det = cv.QRCodeDetector()retval, points, straight_qrcode = det.detectAndDecode(im)

It accepts an input array of an image and returns the following results:

  • retval — Result in a string.
  • points — Array of vertices of the found QR code quadrangle. Will be empty if not found.
  • straight_qrcode — An image containing rectified and binarized QR code.

You should see the following output when you print out the result.

Image for post

Multiple QR codes

From version 4.3.0 onwards, OpenCV-Python comes with multi-detection capabilities. Since I do not have any image that contains two QR codes at the moment, I am going to duplicate it using numpy and place both QR codes side by side. Let’s have a look at the following code snippet.

import cv2 as cv
import numpy as npim = cv.imread('sample.png')
det = cv.QRCodeDetector()retval, decoded_info, points, straight_qrcode = det.detectAndDecodeMulti(np.hstack([im, im]))

detectAndDecodeMulti returns the following result:

  • retval — A boolean value. True if at least one QRCode is detected and decoded.
  • decoded_info — A list of strings that holds the decoded results.
  • points — Array of vertices of the found QR code quadrangle. Will be empty if not found.
  • straight_qrcode — Image containing rectified and binarized QR code.

You should get the following when you print out both the retval and decode_info variables.

True ['https://medium.com/@ngwaifoong92', ''https://medium.com/@ngwaifoong92'']

4. Conclusion

Let’s recap what we have learned today.

We started off with a brief explanation of the QR code. After that, we moved on to install the necessary Python packages via pip install.

We moved on to generate QR Code using the python-qrcode module. It comes with QRCode class, which provides a lot more control for us.

Then, we tested out decoding QR codes using the QRCodeDetector class from OpenCV-Python. In addition, the latest version has multi-detection capabilities, which allow us to detect and decode multiple QR codes from a single image.

Thanks for reading this piece. Hope to see you again in the next article!


Reference

  1. OpenCV QRCodeDetector Documentation

Tags: Python