如何用 Python (最好是纯 Python)解码 QR 码图像?

DR : 我需要一种方法来解码一个图像文件中的二维码,使用(最好是纯的) Python。

我有一个带有二维码的 jpg 文件,我想用 Python 解码它。我发现有几个图书馆声称可以做到这一点:

PyQRCode (请浏览此网页) ,它可以通过简单地提供如下路径来解码图像中的 qr 码:

import sys, qrcode
d = qrcode.Decoder()
if d.decode('out.png'):
print 'result: ' + d.result
else:
print 'error: ' + d.error

因此,我只是使用 sudo pip install pyqrcode安装它。然而,我发现上面示例代码的奇怪之处在于,它只导入 qrcode(而不是 pyqrcode) ,因为我认为 qrcode指的是 这个图书馆,它只能导入 产生的 qr 码图像,这让我有点困惑。所以我尝试了上面的代码与 pyqrcodeqrcode,但都失败在第二行说 AttributeError: 'module' object has no attribute 'Decoder'。此外,网站引用了 Ubuntu 8.10(它出现在6年前) ,我找不到它的公共(git 或其他)存储库来检查最新的提交。于是我转向下一个图书馆:

ZBar (请浏览此网页)声称是 "an open source software suite for reading bar codes from various sources, such as image files.",所以我试着在运行 sudo pip install zbar的 Mac OSX 上安装它。这在 error: command 'cc' failed with exit status 1中失败了。我试图在 这个所以问题的答案中提出建议,但是我似乎不能解决它。所以我决定重新开始:

QRTools ,根据 这篇博文可以使用以下代码轻松解码图像:

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()

所以我试着用 sudo pip install qrtools安装它,但是找不到任何东西。我也试过与 python-qrtoolsqr-toolspython-qrtools和一对夫妇更多的组合,但不幸的是没有用。我想它指的是 这个回购,它说它是基于 ZBar (见上文)。虽然我想在 Heroku 上运行我的代码(因此更喜欢纯 Python 解决方案) ,但是我成功地在 Linux 机器上安装了它(使用 sudo apt-get install python-qrtools)并尝试运行它:

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`)

虽然这看起来像是解码,但好像不是正确的。它还需要 ZBar,因此不是纯 Python。所以我决定再找一个图书馆。

PyXing (请浏览此网页)被认为是流行的 Java ZXing 图书馆的 Python 端口,但是最初和唯一的提交已经有6年的历史了,而且该项目没有自述文件或任何文档。

剩下的我找到了一些 qr-coders (不是 coders)和一些 API 端点,它们可以为您解码。因为我不希望这个服务依赖于其他 API 端点,所以我希望将解码保持在本地。

总而言之,有人知道我如何用(最好是纯粹的) Python 从图像中解码二维码吗?欢迎任何提示!

183261 次浏览

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:

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:

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)

In 2022 using Python 3 this is what worked for me.

Step 1: Install the zbar library

macOS:

brew install zbar

If you get an 'Unable to find zbar shared library' ImportError then do:

mkdir ~/lib
ln -s $(brew --prefix zbar)/lib/libzbar.dylib ~/lib/libzbar.dylib

Ubuntu/Debian Linux:

sudo apt-get update
sudo apt-get install zbar-tools

Windows:

According to the pyzbar project page: Install "Visual C++ Redistributable Packages for Visual Studio 2013. Install vcredist_x64.exe if using 64-bit Python, vcredist_x86.exe if using 32-bit Python."

Step 2: Install the PIP Python packages

pip3 install opencv-python
pip3 install pyzbar

Step 3: Create a Python script

Create a .py script and run the following:

import cv2 as cv
from pyzbar.pyzbar import decode


qrcode_img = 'path/to/qrcode/img.png'
img = cv.imread(qrcode_img)
decoded_data = decode(img)


# parse the decoded zbar data
url = decoded_data[0].data.decode()
print(f'URL: {url}')