SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

Python3で「QRコードの生成」・「QRコードの読み取り」/Pythonサンプル

f:id:arakan_no_boku:20200715210639p:plain

目次

QRコード画像の生成・読み取りをする/Python3サンプル

QRコードは平面(2次元)バーコードです。

バーコードは縦棒(1方向)だけなので情報量が少なく、数字のみで13文字程度しか扱えないのですが、QRコードは平面のドット模様で表現しますので、バーコードの約200倍のデータを扱えます。

二次元バーコードは数字・アルファベット・漢字・ひらがな・記号も扱えます。

 

Pythonのライブラリ

QRコードを含むバーコードの読み書き自体は簡単にできるライブラリがあります。

Python3なので

  • 読み込む方: pyzbar
  • 書き込む方: qrcode

です。

インストールは

pip install pyzbar

pip install qrcode

 です。

pyzbarは、PILといっしょに使うので、はいってない場合は

pip install pillow

もインストールしておきます。 

ライブラリでQRコード・バーコードを読む

こんな感じのバーコード・QRコード画像を読んでみます。

EAN13.jpg

f:id:arakan_no_boku:20200715212921j:plain 

CODE128.jpg

f:id:arakan_no_boku:20200715212949j:plain

QR.jpg

f:id:arakan_no_boku:20200715210639p:plain

上の2つのバーコードは、下にコード化した数字が書いてあります。
最後のQRコードには、この記事のタイトル「QRコードに打ち出したり、読み込んだりするのを、Pythonでやってみる」をコード化しています。

 

ソースコードはこんな感じです。

from pyzbar.pyzbar import decode
from PIL import Image

images = ['CODE128.jpg', 'EAN13.jpg', 'QR.jpg']

for image_file_name in images:
    # バーコードの読取り
    data = decode(Image.open(image_file_name))
    print('\n', image_file_name)
    print(data[0][0].decode('utf-8', 'ignore'))
    print(data[0][1])
    print(data[0][2])
    print(data[0][3])

データの内容([0][0])は、単純に参照できないので、decodeする必要があります。

出力結果は。

CODE128.jpg
0114912345678901
CODE128
Rect(left=8, top=5, width=338, height=108)
[Point(x=8, y=5), Point(x=8, y=113), Point(x=346, y=112), Point(x=346, y=8)]

EAN13.jpg
4901234567894
EAN13
Rect(left=12, top=8, width=148, height=107)
[Point(x=12, y=9), Point(x=12, y=115), Point(x=84, y=115), Point(x=160, y=114), Point(x=160, y=8)]

QR.jpg
QRコードに打ち出したり、読み込んだりするのを、Pythonでやってみる
QRCODE
Rect(left=41, top=41, width=408, height=408)
[Point(x=41, y=41), Point(x=41, y=448), Point(x=449, y=449), Point(x=448, y=41)]

 ということになります。

プログラムとこの出力を見比べると、だいたいわかると思います。 

 

ライブラリでQRコード画像の生成 

上記で読み込んだQRコード(この記事のタイトルをコードにしたもの)を作ります。

ソースコードはこんな感じ。

import qrcode

qr = qrcode.QRCode()
qr.add_data('QRコードに打ち出したり、読み込んだりするのを、Pythonでやってみる')
qr.make()
img = qr.make_image()
img.save('QR.jpg')

まあ、あんまり悩むところは少ないです。

オブジェクト作って、データを追加して、make()して、イメージに出力して保存。

それだけですからね。

いろいろ設定できるみたいですけど、デフォルトでたいていいけます。

 

入力内容の保存にQRコードを応用 するサンプル

入力内容を保存・復元するやり方・・と言っても、大したことではなく。

入力内容を項目ごとに辞書に保存するというのはよくやるので、その辞書を展開・連結した文字列にして、それをQRコードにする。

QRコードから読み取った文字列を、分解して辞書に戻す。

こういうことができればいいんじゃないかな・・ということでやってみます。

以下は、入力内容を辞書に受けた体で、文字列に変換するとしたら、こんな感じかなというソースです。

in_dic = {}
in_dic['id'] = 'AB00001'
in_dic['name'] = 'テスト 太郎'
in_dic['date'] = '2020/01/01'
in_dic['no'] = '1234567'
in_dic['addr'] = '東京都中央区'

instr = ""
for key, value in in_dic.items():
    if len(instr) > 0:
        instr = instr + ',' + str(key) + '=' + str(value)
    else:
        instr = str(key) + '=' + str(value)

これで生成される文字列 は、こうです。

id=AB00001,name=テスト 太郎,date=2020/01/01,no=1234567,addr=東京都中央区

この文字列をQRコードにしたものを読み取った体で、分割して辞書に戻すならこんな感じになります。

r_str = data[0][0].decode('utf-8', 'ignore')
k_list = r_str.split(',')
for x in k_list:
    l_x = str(x).split('=')
    r_dic[str(l_x[0])] = str(l_x[1])

上記の「data[0][0].decode('utf-8', 'ignore')」でr_strにセットされている文字列が

id=AB00001,name=テスト 太郎,date=2020/01/01,no=1234567,addr=東京都中央区

 であるという想定なので、二段階で分割して、キーとバリューにわけて、辞書にセットしているというだけです。

悪くない気はします。

QRコードを使って、キーと情報のペアを受け渡すのは、比較的簡単にできるのはわかりました。

あとは、何をQRコードに含めるか?のアイディア次第ですね。

考えてみれば、面白そうです。

今回はこんなところで。

ではでは。