Invented in 1994 as a type of matrix / two-dimensional barcode, the QR Code (Quick Response Code) has become common place in the modern world. QR Codes appear on a variety of objects from drinks (soda) cans and identification (ID) cards, to advertisements and tickets.
The QR Code can, depending on the verison in use, hold a variety of data such as URLs and configuration. As of 2022 most smart phones can use their camera app or a QR Reader to gather the data from the QR Code. Python has a QR library, called qrcode, that can handle creating and reading QR Codes so I decided to give it a go.
The script I’ve created can be called from the command line using the commands:
python main.py -c DATA TO BE QR'ed HERE
e.g. python main.py -c https://www.geektechstuff.com
or
python main.py -r "QR_IMAGE_FILENAME_HERE"
e.g. python main.py -r “QRImage.png”
The script contains a main function, which takes the command options / arguments and passes them to the appropriate function. The createQR function then creates a QR Code image using options of version (see Wikipedia link below for info), box size and how big the border should be. It also allows for the fill colour and background colour to be altered.
The readQR function takes an image and then uses CV2’s QRCodeDetector to extract the data from the QRCode. The QRCodeDetector outputs three values, but I’m only outputting the data. The args_to_string function is used just to transform the arguments into a string.
import cv2
import qrcode
import sys
def main():
options = [option for option in sys.argv[1:] if option.startswith("-")]
args = [arg for arg in sys.argv[1:] if not arg.startswith("-")]
if "-c" in options:
string = args_to_string(args)
createQR(string)
elif "-r" in options:
string = args_to_string(args)
readQR(string)
else:
raise SystemExit(f"Usage: {sys.argv[0]} n -c DATA n Encodes the data into a QR Code n -r 'QR_IMAGE_FILE' n Reads a QR Code from an image file")
def createQR(data):
'''Takes data, e.g. a URL and encodes as a QR Code image. Outputs a PNG file.'''
qr_image = qrcode.QRCode(
version = 1,
box_size = 10,
border = 5
)
qr_image.add_data(data)
qr_image.make(fit = True)
png_image = qr_image.make_image(
fill_color = 'black',
back_color = 'white'
)
png_image.save('QRImage.png')
return()
def readQR(image):
'''Reads a data from a QR Code image file. Expects speech marks around filename.'''
qr_image = cv2.imread(image)
qr_detector = cv2.QRCodeDetector()
# decode qr_image, returns 3 values
# only interested in the data
data, bbox, straight_qrcode = qr_detector.detectAndDecode(qr_image)
if data is not None:
print(f"Data from QRCode: n {data} ")
return()
def args_to_string(args):
'''Turns list to string so can be used with other functions'''
string = ""
for arg in args:
string += arg
return(string)
if __name__ =="__main__":
main()
I am using Python (3.9.7) with numpy (1.23.3), opencv-python (4.6.0.66), Pillow (9.2.0) and qrcode (7.3.1). I’m currently having a play around with creating command line arguments thanks to a Real Python article at https://realpython.com/python-command-line-arguments/
More information on QR Codes can be found at https://en.wikipedia.org/wiki/QR_code