Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode a QR-code image in (preferably pure) Python?

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 '\xef\xbb\xbfNULL' 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!

like image 657
kramer65 Avatar asked Dec 01 '14 16:12

kramer65


2 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 
like image 162
Anshul Goyal Avatar answered Oct 12 '22 01:10

Anshul Goyal


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)])] 
like image 23
Yuiq Avatar answered Oct 12 '22 01:10

Yuiq