Python 个性化二维码制作

手头有一个这样的需求,制作自定义二维码,要求在二维码中插入图片,作为 A Coder,最直接了当的方式当然是通过书写优美的代码来实现,而人生苦短,我用 Python,陆陆续续捣鼓了几个小时,算是初步完成了,分享下经验。

查阅资料得知,Python 制作二维码的库常见的有 qrcode 和 myqr 两个,下面我分别给出一个 qrcode 和 myqr 制作自定义二维码的一个实例。

但是在动手编码之前,最好还是弄清楚二维码的原理。

二维码原理

二维码的定义

二维条码 (2-dimensional bar code),也称二维码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。

在目前几十种二维条码中,常用的码制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。

  • 堆叠式/行排式二维条码,如,Code 16K、Code 49、PDF41,感兴趣的同学可以查阅资料深入了解下。
  • 矩阵式二维码,最流行莫过于 QR CODE。很多时候,人们经常把 QR CODE 和二维码画上等号,殊不知, QR CODE 只是二维码的一种而已。

二维码是相对于一维码来说的,它们均属于条码,以前在书本或者商品上常印有一维条形码,但现在二维码居多。

QR CODE 的特点

  • 快速读取,QR 即 Quick Response 的缩写,见名知意。
  • 高容量、高密度;理论上内容经过压缩处理后可以存7089个数字,4296 个字母和数字混合字符,2953个8位字节数据,1817个汉字。
  • 支持纠错处理;QR码的纠错能力分为 4 个级别,分别是:

级别

纠错能力

level L

最多能够纠正 7% 的错误

level M

最多能够纠正 15% 的错误

level Q

最多能够纠正 25% 的错误

level H

最多能够纠正 30% 的错误

QR CODE 的大小 (Size) 被定义为版本(Version)。QR CODE 设有从 1 到 40 的不同版本(种类),每个版本都具备固有的码元结构(码元数)。(码元是指构成 QR 码的方形黑白点。) “码元结构”是指二维码中的码元数。从版本 1(21码元×21码元)开始,在纵向和横向各自以4码元为单位递增,一直到版本40(177码元×177码元)。

Tips: 最后了解这些原理后再去看代码,不然可能一头雾水,所谓磨刀不误砍柴工~。

qrcode 库

构造函数 qrcode.QRCode()

qrcode.QRCode(version=20,error_correction=ERROR_CORRECT_H,box_size=10, border=1)

参数名

参数含义

version

控制二维码的大小,取值范围从 1 到 40。取最小值1时,二维码大小为21*21。取值为 None (默认)或者使用 fit=true 参数(默认)时,二维码会自动调整大小。

error_correction

控制二维码纠错级别,四个参数 ERRORCORRECTL/M/Q/H 分别对应上一个表格中四种纠错能力

box_size

控制二维码中每个格子的像素数,默认为 10

border

控制二维码四周留白包含的格子数,默认为4

实例代码

# -*- coding: utf-8 -*-
# author:           inspurer(月小水长)
# pc_type           lenovo
# create_time:      2019/6/11 18:24
# file_name:        my_qrcode.py
# github            https://github.com/inspurer
# qq邮箱            2391527690@qq.com
# 微信公众号         月小水长(ID: inspurer)

import qrcode
from qrcode.constants import ERROR_CORRECT_H
from PIL import Image

def generateQRCode(data, imagePath):
    qr = qrcode.QRCode(version=20,
                       error_correction=ERROR_CORRECT_H,
                       box_size=10, border=1)
    # 添加自定义文本信息
    qr.add_data(data)
    # 二维码自动调整大小
    qr.make(fit=True)

    # 创建二维码图片
    img = qr.make_image()

    # print(img.getpixel((0,0)))
    img = img.convert("RGBA")
    # print(img.getpixel((0,0)))


    icon = Image.open(imagePath)

    img_w, img_h = img.size
    factor = 4
    # // 是整除
    size_w = int(img_w / factor)
    size_h = int(img_h / factor)

    # 划重点,上面两句可以用这句话代替, 更 Pythonic,但是可读性没那么好
    # size_w, size_h = map(lambda x: x//factor, img.size)

    icon_w, icon_h = icon.size
    if icon_w > size_w:
        icon_w = size_w
    if icon_h > size_h:
        icon_h = size_h
    # 做笔记,上面四句可以用下面两句代替,更 Pythonic
    # icon_w = icon_w if icon_w<size_w else size_w
    # icon_h = icon_h if icon_h<size_h else size_h

    # 重新调整 icon 大小使之完美嵌入二维码中
    icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)

    w = int((img_w - icon_w) / 2)
    h = int((img_h - icon_h) / 2)

    # print(icon.getpixel((0,0)),icon.mode)
    icon = icon.convert("RGBA")
    # print(icon.getpixel((0,0)))

    # 把 icon 加到 img 上去
    img.paste(icon, (w, h))

    # 保存二维码
    img.save('my_logo.png')

# 需要在当前路径下放置 raw.jpg
generateQRCode(data='https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzUzMDE5MzQ3Ng==#wechat_redirect', imagePath='raw.jpg')

注释写的比较详细,请慢慢品尝,如有疑问,欢迎留言。

如无意外(记得在工作路径下预留一个图片用作生成二维码用),运行上述代码后会在工作路径下保存生成的二维码,如下:

扫一扫即可看到编码在二维码中的信息,可以是 URL [ 如 add_data("https://inspurer.github.io") ],也可以是一般文本 [ 如 add_data("月小水长") ]

myqr 库

这个库相对而言,没有 qrcode 那么复杂,直接上代码

# -*- coding: utf-8 -*-
# author:           inspurer(月小水长)
# pc_type           lenovo
# create_time:      2019/6/11 18:24
# file_name:        my_qrcode.py
# github            https://github.com/inspurer
# qq邮箱            2391527690@qq.com
# 微信公众号         月小水长(ID: inspurer)


from MyQR import myqr
def myQRTest(data,imgPath):
    version, level, qr_name = myqr.run(
        words=data,  # 不支持中文,支持 0~9,a~z, A~Z 以及常见的常用英文标点符号和空格
        version=2,  # 版本,从 1至 40
        level='H',  # 纠错等级,范围是L、M、Q、H,从左到右依次升高
        picture=imgPath,  # 需要嵌入二维码的图片
        colorized=True,  # True 为彩色,False 为黑白
        contrast=1.0,  # 对比度
        brightness=1.0,  # 亮度
        save_name='my_qrcode2.png',  # 格式可以是 jpg,png,bmp,gif
    )

myQRTest('https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzUzMDE5MzQ3Ng==#wechat_redirect', 'raw.jpg')

本期分享结束,下期再会~

原文发布于微信公众号 - 月小水长(inspurer)

原文发表时间:2019-06-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券