Python3でQRコードを読み込みたかった
Python3でQRコードを読み取るためにPyPIからパッケージを探したのでメモ。
結論から言うとfastzbarlightが簡単かつ早く読み取りができます。
まえおき
C/C++でQRコードやバーコードを読み取らせるライブラリとして有名そうなのはZbarで、公式でPythonのライブラリもありました。 ところがPython2.x用のパッケージしか用意されていなかったので、別のパッケージを探しました。
- zbarlight 1.2 : Python Package Index
- fastzbarlight 0.0.14 : Python Package Index
- libzbar-ctypes 0.1.2 : Python Package Index
- pyzbar 0.1.4 : Python Package Index
- libzbar-cffi 0.2.1 : Python Package Index
fastzbarlightとzbarlightのパッケージはどうやら元のソースコードは同じようです。fastzbarlightはコンパイルオプションを変えて読み取り速度を向上させたらしい(よくわからん)。 で、(fast)zbarlight、libzbar-ctypes、pyzbar、libzbar-cffiのGithubのスターを比べると、1のzbarlightが41でほかよりも多いです。(他のパッケージは0〜10ちょっとくらい)
選ぶ
読み取りに使った画像はこれ。
ソースコードはこっち。
zbarlight (fastzbarlightはzbarlightのモジュール名を変えただけです。)
from PIL import Image import zbarlight import argparse parser = argparse.ArgumentParser() parser.add_argument('FILE', help='QR code image file') args = parser.parse_args() with open(args.FILE, 'rb') as img_file: image = Image.open(img_file) image.load() codes = zbarlight.scan_codes('qrcode', image) print(f'QR codes: {codes}')
libzbar-ctypes
from PIL import Image from libzbar import zbar import argparse parser = argparse.ArgumentParser() parser.add_argument('FILE', help='QR code image file') args = parser.parse_args() with open(args.FILE, 'rb') as img_file: image = Image.open(img_file).convert('L') width, height = image.size raw = image.tobytes() image = zbar.Image(width, height, 'Y800', raw) scanner = zbar.ImageScanner() scanner.scan(image) for symbol in image: print('decode', symbol.type, 'symbol', symbol.data) del(image)
pyzbar
from pyzbar.pyzbar import decode from PIL import Image import argparse parser = argparse.ArgumentParser() parser.add_argument('FILE', help='QR code image file') args = parser.parse_args() with open(args.FILE, 'rb') as img: codes = decode(Image.open(img)) print(f'QR codes: {codes}')
libzbar-cffiはめんどくさくなってやってないです()
time -p
で実行時間を図った結果は次の通り。なお平均とかは取ってないです。
package | real | user | sys |
---|---|---|---|
zbarlight | 1.59 | 1.56 | 0.03 |
fastzbarlight | 1.42 | 1.37 | 0.04 |
libzbar-ctypes | 2.25 | 2.23 | 0.02 |
pyzbar | 2.29 | 2.24 | 0.05 |
fastzbarlightが一番早く実行が終わり、次いでzbarlight、遅れてlibzbar-ctypes、pyzbarという結果になりました。
libzbar-ctypesはスキャンデータがlibzbar.zbar.Imageオブジェクトになるのでforで取り出す処理が入っています。ただその処理をなくしても速度にあまり変化はありませんでした。
結論としては(fast)zbarlightを使っておけば良さそうです。