Python, Pillow, qrcodeでQRコード画像を生成、保存
PythonのQRコード生成ライブラリqrcodeを使うと、簡単にQRコード画像を生成できる。Pillowのメソッドを使って、他の画像の中にQRコードを埋め込んだり、逆にQRコードに画像を埋め込んだりすることも可能。
以下の内容について説明する。
- PythonのQRコード画像生成ライブラリ「qrcode」
- コマンドラインでQRコード画像作成
- PythonのコードでQRコード画像作成
- 生成されるQRコードのバージョン(引数
version
) - 誤り訂正レベル(引数
error_correction
) - セルのサイズ(引数
box_size
) - 余白の幅(引数
border
) - 色(引数
fill_color
,back_color
)
- 生成されるQRコードのバージョン(引数
- QRコードを画像に埋め込む
- QRコードの中に画像を埋め込む
QRコードの検出については以下の記事を参照。厳密には検証していないが、検出精度はZBar(pyzbar)のほうが良さそう。
※QRコードは株式会社デンソーウェーブの登録商標です。
PythonのQRコード画像生成ライブラリ「qrcode」
QRコードは、ISO(ISO/IEC18004)、JIS(JIS-X-0510)で規格化されている、四角い黒白の点(セル)で構成される二次元コード。
PythonにはQRコード画像生成のためのライブラリ「qrcode」がある。
pip
(環境によってはpip3
)でインストールできる。
$ pip install qrcode
Pillow(PIL)を使うのであわせてインストールしておく。
$ pip install pillow
コマンドラインでQRコード画像作成
シンプルなQRコード画像を作成するだけならコマンドラインでOK。
qrcode
をインストールするとqr
コマンドが使えるようになる。
$ qr "text for qrcode" > qrcode.png
この例の場合、text for qrcode
という文字列データを含んだqrcode.png
という名前のQRコード画像ファイルが生成される。文字列の長さに応じて画像サイズが自動で調整される。
QRコードが保持しているのはあくまでも文字列であって、その文字列をどのように処理するかは読み取り側のアプリケーションに依存する。
例えば、スマホのカメラアプリ(QRコード読み取りに対応したもの)では、文字列中にURLが含まれているとそのURLを開くかどうかの通知を表示し、ユーザーが許可すれば規定のブラウザで開くようになっているものが多い。単純にWebサイトに飛ばしたい場合は、URLの文字列をQRコード化すればよい。
PythonのコードでQRコード画像作成
qrcode.make()
でPilImage
型のオブジェクトが生成される。
size
属性で画像のサイズを取得するなど、Pillow(PIL)のImage
型の属性やメソッドなどがそのまま使える。
- Image Module PIL.Image.Image — Pillow (PIL Fork) 6.2.1 documentation
- 関連記事: Pythonの画像処理ライブラリPillow(PIL)の使い方
画像ファイルとして保存するにはsave()
。
import qrcode
img = qrcode.make('test text')
print(type(img))
print(img.size)
# <class 'qrcode.image.pil.PilImage'>
# (290, 290)
img.save('data/dst/qrcode_test.png')
QRCode
クラスを使って、細かい設定を変更することもできる。
基本の流れは以下の通り。
qr = qrcode.QRCode()
qr.add_data('test text')
qr.make()
img = qr.make_image()
img.save('data/dst/qrcode_test2.png')
もろもろの設定をすると以下のようになる。
qr = qrcode.QRCode(
version=12,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=2,
border=8
)
qr.add_data('test text')
qr.make()
img = qr.make_image(fill_color="red", back_color="#23dda0")
img.save('data/dst/qrcode_test2_2.png')
以下、それぞれの引数について説明する。
生成されるQRコードのバージョン(引数version)
コンストラクタQRCode()
の引数version
で、生成されるQRコードのバージョンを設定できる。
QRコードの情報量とバージョンの関係についてはデンソーウェーブ公式の以下のページを参照。
バージョンの値が大きくなるとQRコードに含まれるセル(黒白の四角)の数が多くなり、画像サイズと情報量が増える。version=1
が最小でversion=40
が最大。
引数version
を与えることで、最適なバージョン(最小限のサイズ)よりも大きいQRコード画像を生成できる。データ内容が異なる複数のQRコードを同じ大きさで作成したいときに便利。
なお、小さいバージョンを指定しても、データが収まらない場合は自動的にデータが収まる最小限のバージョンになる。
誤り訂正レベル(引数error_correction)
QRCode()
の引数error_correction
で誤り訂正レベルを設定できる。
以下の4種類がある。カッコ内は誤り訂正能力(全コードワードに対する誤り訂正率)。
qrcode.constants.ERROR_CORRECT_L
(約7%)qrcode.constants.ERROR_CORRECT_M
(約15%, デフォルト)qrcode.constants.ERROR_CORRECT_Q
(約25%)qrcode.constants.ERROR_CORRECT_H
(約30%)
QRコードの誤り訂正機能についてはデンソーウェーブ公式の以下のページを参照。
同じ長さの文字列をQRコード化する場合、誤り訂正レベルを高くすると生成されるQRコード画像サイズが大きくなる。
セルのサイズ(引数box_size)
QRCode()
の引数box_size
でセル(四角い黒白の点)のサイズ(ピクセル)を設定できる。
version
が同じ(セルの数が同じ)でも、box_size
を変更することで生成される画像のサイズを変更できる。
デフォルトは10
。
余白の幅(引数border)
QRCode()
の引数border
で外周の余白の幅(セルの数)を設定できる。box_size * border
が余白の幅のピクセルとなる。
デフォルトは4で、仕様上の最小幅になっている。
色(引数fill_color, back_color)
make_image()
メソッドの引数fill_color
, back_color
で色を設定できる。QRCode()
の引数ではないので注意。
black
, white
, red
などの名前や#xxxxxx
のスタイルで指定する。
QRコードを画像に埋め込む
PilImage
型のオブジェクトは、PillowのImage
オブジェクトのpaste()
メソッドでそのまま他の画像に貼り付けられる。
右下隅にQRコードを貼り付ける例。
import qrcode
from PIL import Image
img_bg = Image.open('data/src/lena.jpg')
qr = qrcode.QRCode(box_size=2)
qr.add_data('I am Lena')
qr.make()
img_qr = qr.make_image()
pos = (img_bg.size[0] - img_qr.size[0], img_bg.size[1] - img_qr.size[1])
img_bg.paste(img_qr, pos)
img_bg.save('data/dst/qr_lena.png')
paste()
メソッドについての詳細は以下の記事を参照。
QRコードの中に画像を埋め込む
QRコードの中に画像を埋め込むのも簡単。
なお、QRコードにイラストなどの画像を重ねると規格から外れるため、公式には非推奨とされている。
色を付けたりイラストを入れるような使い方をしても問題ありませんか?
QRコードにイラストを重ねたり、デザインをのせて変形してしまうと、ちょっとした汚れや欠けでも読み取り出来なくなったり、読み取りの反応が悪くなってしまうことがありますので推奨しておりません。安定した読み取りという面から、JIS、ISOの規格で制定されている内容に従ってご利用いただくことを推奨しております。
また、QRコードにイラストを重ねたりデザインを乗せるということは、QRコードの規格から外れ「QRコードではないもの」となってしまう可能性がございます。デンソーウェーブは、JIS、ISOの規格に沿ったQRコードに限っては特許権を行使しませんが、規格を逸脱したQRコードについてはこの限りではございませんので、特許権を行使させていただくこともございます。
face = Image.open('data/src/lena.jpg').crop((175, 90, 235, 150))
qr_big = qrcode.QRCode(
error_correction=qrcode.constants.ERROR_CORRECT_H
)
qr_big.add_data('I am Lena')
qr_big.make()
img_qr_big = qr_big.make_image().convert('RGB')
pos = ((img_qr_big.size[0] - face.size[0]) // 2, (img_qr_big.size[1] - face.size[1]) // 2)
img_qr_big.paste(face, pos)
img_qr_big.save('data/dst/qr_lena2.png')
埋め込む画像のサイズにもよるが、誤り訂正レベル(引数error_correction
)を高めに設定しておいたほうが無難。また、白黒のQRコードにカラー画像を埋め込む場合は、QRコード画像をconvert('RGB')
でRGB
モードに変換する必要がある。