Barcodes and QR Codes Decoder in Python | by Ng Wai Foong | Towards Data Science

By reading this piece, you will learn about the tips and tricks to generate one-dimensional barcodes in different formats as well as Quick Response code (QR Code) generation. Besides, this tutorial will outline the methods to decode both the barcode and QR Code using the same Python library. Previously, I have covered a tutorial on How to Generate and Decode QR Codes in Python which used OpenCV to decode QR Codes. In this tutorial, I will be using another module called pyzbar for decoding instead. Based on the official documentation, pyzbar is
“... a pure Python library that reads one-dimensional barcodes and QR codes using the zbar library, an open source software suite for reading bar codes from various sources, such as video streams, image files and raw intensity sensors. It supports many popular symbologies (types of bar codes) including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.”
Based on the experiments that I have conducted, pyzbar performs better compared to python-opencv in terms of accuracy when decoding QR Codes. On top of that, pyzbar is able to decode barcodes as well.
Let’s proceed to the next section and start installing the necessary modules.
It is highly recommended to setup a virtual environment before you continue with the installation. You can easily install all the modules via pip install.
Our first module is the python-barcode package which helps to generate one-dimensional barcodes based on the formats that we have specified. Run the following command to install it
pip install python-barcode
By default, result will be exported as SVG. You need to install additional dependencies such as Pillow. You can choose to install the dependencies independently or together with python-barcode as follows:
pip install python-barcode[images]
You can install qrcode package individually via the following command
pip install qrcode
Optionally, you can include the Pillow dependencies together with the standard installation as well
pip install qrcode[pil]
Installation for pyzbar is slightly complicated and depends on the operating system of your machine. For Windows user, zbar DLL comes together with the Windows Python wheels.
For Mac OS X, you can install the zbar shared library via the following command
brew install zbar
The following command should be used if you are using Linux.
sudo apt-get install libzbar0
Once you are done with it, run the following command to install pyzbar Python package.
pip install pyzbar
In fact, it also support command-line functionality which allows you to run it directly in command line. To do so, you should install it as follows:
pip install pyzbar[scripts]
In this section, we are going to generate barcodes using the python-barcode package.
At the time of this writing, this package supports the following formats:
EAN-8
EAN-13
EAN-14
UPC-A
JAN
ISBN-10
ISBN-13
ISSN
Code 39
Code 128
PZN
I am going to generate a new barcode using the EAN13 format. The result will be in PNG format.
Let’s add the following import statement. ImageWriter is needed if you are saving the results as images. Otherwise, it will be defaulted to SVG.
from barcode import EAN13from barcode.writer import ImageWriter
Continue appending the following code below it. Since we are writing an image, you need to specify the filemode as wb. For your information, EAN13 accepts a string which contains 12 digits instead of 13. The last digit is a checksum and will be generated automatically. If your input is a 13 digits string, the last digit will be ignored.
with open('barcode.png', 'wb') as f:    EAN13('123456789102', writer=ImageWriter()).write(f)
The complete code snippet is as follows:
It should generate the following image when you run the Python file.
Generation of QR Code is slightly complicated compared to barcode due to the fact that QR Code is 2-dimensional.
Add the following import statement
import qrcodefrom PIL import Image
Create an instance of QRCode object with the following parameters
qr = qrcode.QRCode(    version=1,    error_correction=qrcode.constants.ERROR_CORRECT_H,    box_size=10,    border=4,)
version — Control the size of the QR Code. It accepts an integer from 1 to 40. Version 1 consists of 21 x 21 matrix.
error_correction — Control the error correction used for the QR Code.
box_size — Control the number of pixels of each boxes of the QR code.
border — Control the boxes thickness of the border. The default is value is 4 which is also the minimum value according to the specification.
There are 4 constants available for error_correction. The higher errors can be corrected, the better it is.
ERROR_CORRECT_L — About 7% or less errors can be corrected.
ERROR_CORRECT_M — About 15% or less errors can be corrected. This is the default value.
ERROR_CORRECT_Q — About 25% or less errors can be corrected.
ERROR_CORRECT_H — About 30% or less errors can be corrected.
Continue appending the following code snippet below it. Replace the input parameter for add_data based on your own use cases.
qr.add_data("https://medium.com/@ngwaifoong92")qr.make(fit=True)img = qr.make_image(fill_color="black", back_color="white")img.save("qrcode.png")
You can find the complete code in the following gist.
You should get a QR Code once you ran the code. In my case, it looks like this.
Once you are done with it, proceed to the next section and start implementing our decoder.
One main feature of pyzbar is that decoding is done directly using the same function. In addition, it supports decoding multiple barcodes or QR Codes in a single image. Import the decode() function from the module as follows:
from pyzbar.pyzbar import decode
You can pass either an instance of PIL.Image or an instance of numpy.ndarray. You can easily load an image into numpy.ndarry using OpenCV. For loading with PIL, use the following code
from PIL import Imageimg = Image.open('qrcode.png')
Here is an example of how you can load your image using OpenCV.
import cv2img = cv2.imread('qrcode.png')
Append the following code below it. It will print out the results as strings.
result = decode(img)
decode() function returns a list of namedtuple called Decoded. Each of them contains the following fields:
data — The decoded string in bytes. You need to decode it using utf8 to get a string.
type — Only useful for barcodes as it outlines the barcode format.
rect — A Rect object which represents the captured localization area.
polygon — A list of Point instances which represents the barcode or QR Code.
If you were to print out the whole returned result, you should get the following output
[Decoded(data=b'https://medium.com/@ngwaifoong92', type='QRCODE', rect=Rect(left=40, top=40, width=330, height=330), polygon=[Point(x=40, y=40), Point(x=40, y=369), Point(x=370, y=370), Point(x=369, y=40)])]
Use the following code to loop over each of the element and print out the decoded string
for i in result:    print(i.data.decode("utf-8"))
The complete code can be found at the following gist.
Let’s recap what we have learned today.
We started off with some explanations on the fundamental concepts behind python-barcode, qrcode and pyzbar.
After that, we moved on to install the necessary modules. Installation is pretty straightforward with pip install.
Once we are done with it, we implemented the generation of both barcodes and QR Codes with the configuration parameters of our choice.
Finally, we utilized pyzbar module to decode the images that we have generated earlier.
Thanks for reading this piece. Hope to see you again in the next article!
python-barcode Githubqrcode Githubpyzbar Github