👋

zxingのPython拡張モジュールで中央にアイコンの付いたQRコードを生成する

2021/05/12に公開

中央にアイコンの付いたQRコードの生成の仕方について紹介します。zxingモジュールのインストール方法については、次の記事で取り扱っています。
https://zenn.dev/nnabeyang/articles/fe93f9a85130781e7e5c

zennのロゴを中央に『ZennのMarkdown記法一覧』のURLの埋め込まれたQRコードを生成してみます(Zennのロゴはメディアキットからダウンロードしました)。

import cv2
import zxing
from PIL import Image, ImageDraw

isize = 300
lsize = 40
msize = lsize + 10
zenn_url = "https://zenn.dev/zenn/articles/markdown-guide"
logo = cv2.imread('./zenn-logo/logo.png')
logo = logo[:, 6:1000, :] # ロゴ部分を適当に切り抜く。jupyter上で調整すると楽
logo = cv2.resize(logo, (lsize, lsize), interpolation = cv2.INTER_AREA)
logo = cv2.cvtColor(logo, cv2.COLOR_BGR2RGB)
logo = Image.fromarray(logo).convert('RGBA')

bg = Image.new('RGBA', (isize, isize), (255, 255, 255, 255))
bg.paste(logo, ((isize - lsize) // 2, (isize - lsize) // 2))
mask_circle = Image.new('L', bg.size, 0)
draw = ImageDraw.Draw(mask_circle)
min_size = (isize - msize) // 2
max_size = min_size + msize
draw.ellipse((min_size, min_size, max_size, max_size), fill=255)

img = zxing.write_barcode(zxing.BarcodeFormat.QR_CODE, zenn_url)
img = cv2.resize(img, bg.size, interpolation = cv2.INTER_AREA)
img = Image.fromarray(img)

img = img.convert('RGBA')
img.paste(bg, (0, 0), mask=mask_circle)
img.save('zenn_qr.png')

出来ました。ポイントとしてはzxingの生成するQRコードのサイズが小さいので拡大する必要があるのですが、そのときcv2.INTER_AREAを選ぶと劣化せずに拡大できます。中央にロゴがあるのにURLが読み取れるのは、QRコード自身が誤り訂正機能を持っていて、ある程度コードが消えても読める性質を利用したものです。

Discussion