How to decode a QR-code image in (preferably pure) Python?
Question:
TL;DR: I need a way to decode a QR-code from an image file using (preferable pure) Python.
I’ve got a jpg file with a QR-code which I want to decode using Python. I’ve found a couple libraries which claim to do this:
PyQRCode (website here) which supposedly can decode qr codes from images by simply providing a path like this:
import sys, qrcode
d = qrcode.Decoder()
if d.decode('out.png'):
print 'result: ' + d.result
else:
print 'error: ' + d.error
So I simply installed it using sudo pip install pyqrcode
. The thing I find strange about the example code above however, is that it only imports qrcode
(and not pyqrcode
though) Since I think qrcode
refers to this library which can only generate qr-code images it kind of confused me. So I tried the code above with both pyqrcode
and qrcode
, but both fail at the second line saying AttributeError: 'module' object has no attribute 'Decoder'
. Furthermore, the website refers to Ubuntu 8.10 (which came out more than 6 years ago) and I can’t find a public (git or other) repository of it to check the latest commit. So I moved on to the next library:
ZBar (website here) claims to be "an open source software suite for reading bar codes from various sources, such as image files."
So I tried installing it on Mac OSX running sudo pip install zbar
. This fails with error: command 'cc' failed with exit status 1
. I tried to suggestions in the answers to this SO question, but I can’t seem to solve it. So I decided to move on again:
QRTools, which according to this blogpost can decode images easily by using the following code:
from qrtools import QR
myCode = QR(filename=u"/home/psutton/Documents/Python/qrcodes/qrcode.png")
if myCode.decode():
print myCode.data
print myCode.data_type
print myCode.data_to_string()
So I tried installing it using sudo pip install qrtools
, which can’t find anything. I also tried it with python-qrtools
, qr-tools
, python-qrtools
and a couple more combinations, but unfortunately to no avail. I suppose it refers to this repo which says it is based on ZBar (see above). Although I want to run my code on Heroku (and thus prefer a pure Python solution) I successfully installed it on a Linux box (with sudo apt-get install python-qrtools
) and tried running it:
from qrtools import QR
c = QR(filename='/home/kramer65/qrcode.jpg')
c.data # prints u'NULL'
c.data_type # prints u'text'
c.data_to_string() # prints 'xefxbbxbfNULL' where I expect an int (being `1234567890`)
Although this seems to decode it, It doesn’t seem to do it correctly. It furthermore needs ZBar and is thus not pure Python. So I decided to find yet another library.
PyXing (website here) is supposedly a Python port of the popular Java ZXing library, but the initial and only commit is 6 years old and the project has no readme or documentation whatsoever.
For the rest I found a couple qr-encoders (not decoders) and some API endpoints which can decode for you. Since I don’t like this service to be dependent on other API endpoints I would want to keep the decoding local though.
So to conclude; would anybody know how I can decode QR-codes from images in (preferable pure) Python? All tips are welcome!
Answers:
You can try the following steps and code using qrtools
:
-
Create a qrcode
file, if not already existing
- I used
pyqrcode
for doing this, which can be installed using pip install pyqrcode
-
And then use the code:
>>> import pyqrcode
>>> qr = pyqrcode.create("HORN O.K. PLEASE.")
>>> qr.png("horn.png", scale=6)
-
Decode an existing qrcode
file using qrtools
- Install
qrtools
using sudo apt-get install python-qrtools
-
Now use the following code within your python prompt
>>> import qrtools
>>> qr = qrtools.QR()
>>> qr.decode("horn.png")
>>> print qr.data
u'HORN O.K. PLEASE.'
Here is the complete code in a single run:
In [2]: import pyqrcode
In [3]: qr = pyqrcode.create("HORN O.K. PLEASE.")
In [4]: qr.png("horn.png", scale=6)
In [5]: import qrtools
In [6]: qr = qrtools.QR()
In [7]: qr.decode("horn.png")
Out[7]: True
In [8]: print qr.data
HORN O.K. PLEASE.
Caveats
- You might need to install
PyPNG
using pip install pypng
for using pyqrcode
-
In case you have PIL
installed, you might get IOError: decoder zip not available
. In that case, try uninstalling and reinstalling PIL
using:
pip uninstall PIL
pip install PIL
-
If that doesn’t work, try using Pillow
instead
pip uninstall PIL
pip install pillow
I’m answering only the part of the question about zbar
installation.
I spent nearly half an hour a few hours to make it work on Windows + Python 2.7 64-bit, so here are additional notes to the accepted answer:
-
-
Install it with pip install zbar-0.10-cp27-none-win_amd64.whl
-
If Python reports an ImportError: DLL load failed: The specified module could not be found.
when doing import zbar
, then you will just need to install the Visual C++ Redistributable Packages for VS 2013 (I spent a lot of time here, trying to recompile unsuccessfully…)
-
Required too: libzbar64-0.dll must be in a folder which is in the PATH. In my case I copied it to “C:Python27libzbar64-0.dll” (which is in the PATH). If it still does not work, add this:
import os
os.environ['PATH'] += ';C:\Python27'
import zbar
PS: Making it work with Python 3.x is even more difficult: Compile zbar for Python 3.x.
PS2: I just tested pyzbar with pip install pyzbar
and it’s MUCH easier, it works out-of-the-box (the only thing is you need to have VC Redist 2013 files installed). It is also recommended to use this library in this pyimagesearch.com article.
The following code works fine with me:
brew install zbar
pip install pyqrcode
pip install pyzbar
For QR code image creation:
import pyqrcode
qr = pyqrcode.create("test1")
qr.png("test1.png", scale=6)
For QR code decoding:
from PIL import Image
from pyzbar.pyzbar import decode
data = decode(Image.open('test1.png'))
print(data)
that prints the result:
[Decoded(data=b'test1', type='QRCODE', rect=Rect(left=24, top=24, width=126, height=126), polygon=[Point(x=24, y=24), Point(x=24, y=150), Point(x=150, y=150), Point(x=150, y=24)])]
There is a library called BoofCV which claims to better than ZBar and other libraries.
Here are the steps to use that (any OS).
Pre-requisites:
- Ensure JDK 14+ is installed and set in $PATH
pip install pyboof
Class to decode:
import os
import numpy as np
import pyboof as pb
pb.init_memmap() #Optional
class QR_Extractor:
# Src: github.com/lessthanoptimal/PyBoof/blob/master/examples/qrcode_detect.py
def __init__(self):
self.detector = pb.FactoryFiducial(np.uint8).qrcode()
def extract(self, img_path):
if not os.path.isfile(img_path):
print('File not found:', img_path)
return None
image = pb.load_single_band(img_path, np.uint8)
self.detector.detect(image)
qr_codes = []
for qr in self.detector.detections:
qr_codes.append({
'text': qr.message,
'points': qr.bounds.convert_tuple()
})
return qr_codes
Usage:
qr_scanner = QR_Extractor()
output = qr_scanner.extract('Your-Image.jpg')
print(output)
Tested and works on Python 3.8 (Windows & Ubuntu)
For Windows using ZBar
Pre-requisites:
- Install ZBar by either:
- Install Chocolatey and
choco install zbar
- Or use Windows Installer for ZBar
pip install pyzbar
To decode:
from PIL import Image
from pyzbar import pyzbar
img = Image.open('My-Image.jpg')
output = pyzbar.decode(img)
print(output)
Alternatively, you can also try using ZBarLight
by setting it up as mentioned here:
https://pypi.org/project/zbarlight/
I found a new and effective way, just using cv2. The code below will decode a QR code.
import cv2
# Name of the QR Code Image file
filename = "attandence_Record_QR_code.png"
# read the QRCODE image
image = cv2.imread(filename)
# initialize the cv2 QRCode detector
detector = cv2.QRCodeDetector()
# detect and decode
data, vertices_array, binary_qrcode = detector.detectAndDecode(image)
# if there is a QR code
# print the data
if vertices_array is not None:
print("QRCode data:")
print(data)
else:
print("There was some error")
PyBoof is a wrapper around BoofCV and has an easy to use QR Code reader. It also give you access to a ton of information about the QR, e.g. number of bit errors, precise location, raw message, …
image = pb.load_single_band(data_path, np.uint8)
detector = pb.FactoryFiducial(np.uint8).qrcode()
detector.detect(image)
for qr in detector.detections:
print("Message: " + qr.message)
print(" at: " + str(qr.bounds))
first intsall
pip install pyzbar
then:
import cv2 as cv
from pyzbar.pyzbar import decode
img=cv.imread('/path/img.jpg')
objs=decode(img)
for obj in objs:
print('data: ', obj)
For people, who can’t install sudo apt-get install python-qrtools
, try to sudo apt install python3-qrtools
TL;DR: I need a way to decode a QR-code from an image file using (preferable pure) Python.
I’ve got a jpg file with a QR-code which I want to decode using Python. I’ve found a couple libraries which claim to do this:
PyQRCode (website here) which supposedly can decode qr codes from images by simply providing a path like this:
import sys, qrcode
d = qrcode.Decoder()
if d.decode('out.png'):
print 'result: ' + d.result
else:
print 'error: ' + d.error
So I simply installed it using sudo pip install pyqrcode
. The thing I find strange about the example code above however, is that it only imports qrcode
(and not pyqrcode
though) Since I think qrcode
refers to this library which can only generate qr-code images it kind of confused me. So I tried the code above with both pyqrcode
and qrcode
, but both fail at the second line saying AttributeError: 'module' object has no attribute 'Decoder'
. Furthermore, the website refers to Ubuntu 8.10 (which came out more than 6 years ago) and I can’t find a public (git or other) repository of it to check the latest commit. So I moved on to the next library:
ZBar (website here) claims to be "an open source software suite for reading bar codes from various sources, such as image files."
So I tried installing it on Mac OSX running sudo pip install zbar
. This fails with error: command 'cc' failed with exit status 1
. I tried to suggestions in the answers to this SO question, but I can’t seem to solve it. So I decided to move on again:
QRTools, which according to this blogpost can decode images easily by using the following code:
from qrtools import QR
myCode = QR(filename=u"/home/psutton/Documents/Python/qrcodes/qrcode.png")
if myCode.decode():
print myCode.data
print myCode.data_type
print myCode.data_to_string()
So I tried installing it using sudo pip install qrtools
, which can’t find anything. I also tried it with python-qrtools
, qr-tools
, python-qrtools
and a couple more combinations, but unfortunately to no avail. I suppose it refers to this repo which says it is based on ZBar (see above). Although I want to run my code on Heroku (and thus prefer a pure Python solution) I successfully installed it on a Linux box (with sudo apt-get install python-qrtools
) and tried running it:
from qrtools import QR
c = QR(filename='/home/kramer65/qrcode.jpg')
c.data # prints u'NULL'
c.data_type # prints u'text'
c.data_to_string() # prints 'xefxbbxbfNULL' where I expect an int (being `1234567890`)
Although this seems to decode it, It doesn’t seem to do it correctly. It furthermore needs ZBar and is thus not pure Python. So I decided to find yet another library.
PyXing (website here) is supposedly a Python port of the popular Java ZXing library, but the initial and only commit is 6 years old and the project has no readme or documentation whatsoever.
For the rest I found a couple qr-encoders (not decoders) and some API endpoints which can decode for you. Since I don’t like this service to be dependent on other API endpoints I would want to keep the decoding local though.
So to conclude; would anybody know how I can decode QR-codes from images in (preferable pure) Python? All tips are welcome!
You can try the following steps and code using qrtools
:
-
Create a
qrcode
file, if not already existing- I used
pyqrcode
for doing this, which can be installed usingpip install pyqrcode
-
And then use the code:
>>> import pyqrcode >>> qr = pyqrcode.create("HORN O.K. PLEASE.") >>> qr.png("horn.png", scale=6)
- I used
-
Decode an existing
qrcode
file usingqrtools
- Install
qrtools
usingsudo apt-get install python-qrtools
-
Now use the following code within your python prompt
>>> import qrtools >>> qr = qrtools.QR() >>> qr.decode("horn.png") >>> print qr.data u'HORN O.K. PLEASE.'
- Install
Here is the complete code in a single run:
In [2]: import pyqrcode
In [3]: qr = pyqrcode.create("HORN O.K. PLEASE.")
In [4]: qr.png("horn.png", scale=6)
In [5]: import qrtools
In [6]: qr = qrtools.QR()
In [7]: qr.decode("horn.png")
Out[7]: True
In [8]: print qr.data
HORN O.K. PLEASE.
Caveats
- You might need to install
PyPNG
usingpip install pypng
for usingpyqrcode
-
In case you have
PIL
installed, you might getIOError: decoder zip not available
. In that case, try uninstalling and reinstallingPIL
using:pip uninstall PIL pip install PIL
-
If that doesn’t work, try using
Pillow
insteadpip uninstall PIL pip install pillow
I’m answering only the part of the question about zbar
installation.
I spent nearly half an hour a few hours to make it work on Windows + Python 2.7 64-bit, so here are additional notes to the accepted answer:
-
Install it with
pip install zbar-0.10-cp27-none-win_amd64.whl
-
If Python reports an
ImportError: DLL load failed: The specified module could not be found.
when doingimport zbar
, then you will just need to install the Visual C++ Redistributable Packages for VS 2013 (I spent a lot of time here, trying to recompile unsuccessfully…) -
Required too: libzbar64-0.dll must be in a folder which is in the PATH. In my case I copied it to “C:Python27libzbar64-0.dll” (which is in the PATH). If it still does not work, add this:
import os os.environ['PATH'] += ';C:\Python27' import zbar
PS: Making it work with Python 3.x is even more difficult: Compile zbar for Python 3.x.
PS2: I just tested pyzbar with pip install pyzbar
and it’s MUCH easier, it works out-of-the-box (the only thing is you need to have VC Redist 2013 files installed). It is also recommended to use this library in this pyimagesearch.com article.
The following code works fine with me:
brew install zbar
pip install pyqrcode
pip install pyzbar
For QR code image creation:
import pyqrcode
qr = pyqrcode.create("test1")
qr.png("test1.png", scale=6)
For QR code decoding:
from PIL import Image
from pyzbar.pyzbar import decode
data = decode(Image.open('test1.png'))
print(data)
that prints the result:
[Decoded(data=b'test1', type='QRCODE', rect=Rect(left=24, top=24, width=126, height=126), polygon=[Point(x=24, y=24), Point(x=24, y=150), Point(x=150, y=150), Point(x=150, y=24)])]
There is a library called BoofCV which claims to better than ZBar and other libraries.
Here are the steps to use that (any OS).
Pre-requisites:
- Ensure JDK 14+ is installed and set in $PATH
pip install pyboof
Class to decode:
import os
import numpy as np
import pyboof as pb
pb.init_memmap() #Optional
class QR_Extractor:
# Src: github.com/lessthanoptimal/PyBoof/blob/master/examples/qrcode_detect.py
def __init__(self):
self.detector = pb.FactoryFiducial(np.uint8).qrcode()
def extract(self, img_path):
if not os.path.isfile(img_path):
print('File not found:', img_path)
return None
image = pb.load_single_band(img_path, np.uint8)
self.detector.detect(image)
qr_codes = []
for qr in self.detector.detections:
qr_codes.append({
'text': qr.message,
'points': qr.bounds.convert_tuple()
})
return qr_codes
Usage:
qr_scanner = QR_Extractor()
output = qr_scanner.extract('Your-Image.jpg')
print(output)
Tested and works on Python 3.8 (Windows & Ubuntu)
For Windows using ZBar
Pre-requisites:
- Install ZBar by either:
- Install Chocolatey and
choco install zbar
- Or use Windows Installer for ZBar
- Install Chocolatey and
pip install pyzbar
To decode:
from PIL import Image
from pyzbar import pyzbar
img = Image.open('My-Image.jpg')
output = pyzbar.decode(img)
print(output)
Alternatively, you can also try using ZBarLight
by setting it up as mentioned here:
https://pypi.org/project/zbarlight/
I found a new and effective way, just using cv2. The code below will decode a QR code.
import cv2
# Name of the QR Code Image file
filename = "attandence_Record_QR_code.png"
# read the QRCODE image
image = cv2.imread(filename)
# initialize the cv2 QRCode detector
detector = cv2.QRCodeDetector()
# detect and decode
data, vertices_array, binary_qrcode = detector.detectAndDecode(image)
# if there is a QR code
# print the data
if vertices_array is not None:
print("QRCode data:")
print(data)
else:
print("There was some error")
PyBoof is a wrapper around BoofCV and has an easy to use QR Code reader. It also give you access to a ton of information about the QR, e.g. number of bit errors, precise location, raw message, …
image = pb.load_single_band(data_path, np.uint8)
detector = pb.FactoryFiducial(np.uint8).qrcode()
detector.detect(image)
for qr in detector.detections:
print("Message: " + qr.message)
print(" at: " + str(qr.bounds))
first intsall
pip install pyzbar
then:
import cv2 as cv
from pyzbar.pyzbar import decode
img=cv.imread('/path/img.jpg')
objs=decode(img)
for obj in objs:
print('data: ', obj)
For people, who can’t install sudo apt-get install python-qrtools
, try to sudo apt install python3-qrtools