Python3 生成和识别二维码


[写在前面] 在当今社会中,二维码的使用非常的广泛。当然作为一名充满好奇心又爱装逼的 coder 怎么能不会使用二维码编码自己想表达的内容呢,尤其是用在装逼和找对象上。


问题描述

一番学习和搜索之后发现,对于使用JavaJSPAndroidJS编程的小伙伴来说,网上的资料是一箩筐,基本找一找就可以“板砖”了。但是作为拥有众多包的Python来说,怎么搜来搜去都是非常陈旧的资料,很多都是针对Python2的代码,而且大多都不能再使用了。除此之外,其中还有很多文章都只有针对Python生成一个QR Code的解释和代码,而如何去识别一个二维码的却非常的少。虽然也有,但是不是使用Jpython去调用Java中的工具包去识别,就是需要大量的代码去实现。作为一个小白,就希望简单的调用就能达到自己的效果就好。因此,在搜索了大量博客、网页之后,在pypi上我找到了两个库能够很好的解决问题。

这两个库不仅同时支持Python2 Python3,而且调用方式非常的简单只需要简单的一两句话就能完事,而且都是pypi上的包,能够通过pip进行安装和管理开源且拥有自己的github,提供有官方文档,可以快速使用。


这两个库分别是:

  • 用于生成二维码的 qrcode
  • 用于识别二维码的pyzbar

代码

是不是很迫不及待?话不多说,先上代码。我已经包装好了函数,直接Ctrl + C Ctrl + V,就能用了。

# -*- coding:utf-8 -*-

__author__ = "HouZhipeng"
__blog__ = "https://blog.csdn.net/Zhipeng_Hou"

import os

import qrcode
from PIL import Image
from pyzbar import pyzbar


def make_qr_code_easy(content, save_path=None):
    """
    Generate QR Code by default
    :param content: The content encoded in QR Codeparams
    :param save_path: The path where the generated QR Code image will be saved in.
                      If the path is not given the image will be opened by default.
    """
    img = qrcode.make(data=content)
    if save_path:
        img.save(save_path)
    else:
        img.show()


def make_qr_code(content, save_path=None):
    """
    Generate QR Code by given params
    :param content: The content encoded in QR Code
    :param save_path: The path where the generated QR Code image will be saved in.
                      If the path is not given the image will be opened by default.
    """
    qr_code_maker = qrcode.QRCode(version=2,
                                  error_correction=qrcode.constants.ERROR_CORRECT_M,
                                  box_size=8,
                                  border=1,
                                  )
    qr_code_maker.add_data(data=content)
    qr_code_maker.make(fit=True)
    img = qr_code_maker.make_image(fill_color="black", back_color="white")
    if save_path:
        img.save(save_path)
    else:
        img.show()


def make_qr_code_with_icon(content, icon_path, save_path=None):
    """
    Generate QR Code with an icon in the center
    :param content: The content encoded in QR Code
    :param icon_path: The path of icon image
    :param save_path: The path where the generated QR Code image will be saved in.
                      If the path is not given the image will be opened by default.
    :exception FileExistsError: If the given icon_path is not exist.
                                This error will be raised.
    :return:
    """
    if not os.path.exists(icon_path):
        raise FileExistsError(icon_path)

    # First, generate an usual QR Code image
    qr_code_maker = qrcode.QRCode(version=4,
                                  error_correction=qrcode.constants.ERROR_CORRECT_H,
                                  box_size=8,
                                  border=1,
                                  )
    qr_code_maker.add_data(data=content)
    qr_code_maker.make(fit=True)
    qr_code_img = qr_code_maker.make_image(fill_color="black", back_color="white").convert('RGBA')

    # Second, load icon image and resize it
    icon_img = Image.open(icon_path)
    code_width, code_height = qr_code_img.size
    icon_img = icon_img.resize((code_width // 4, code_height // 4), Image.ANTIALIAS)

    # Last, add the icon to original QR Code
    qr_code_img.paste(icon_img, (code_width * 3 // 8, code_width * 3 // 8))

    if save_path:
        qr_code_img.save(save_path)
    else:
        qr_code_img.show()


def decode_qr_code(code_img_path):
    """
    Decode the given QR Code image, and return the content
    :param code_img_path: The path of QR Code image.
    :exception FileExistsError: If the given code_img_path is not exist.
                                This error will be raised.
    :return: The list of decoded objects
    """
    if not os.path.exists(code_img_path):
        raise FileExistsError(code_img_path)

    # Here, set only recognize QR Code and ignore other type of code
    return pyzbar.decode(Image.open(code_img_path), symbols=[pyzbar.ZBarSymbol.QRCODE])


if __name__ == "__main__":

    make_qr_code_easy("make_qr_code_easy", "qrcode.png")
    results = decode_qr_code("qrcode.png")
    if len(results):
        print(results[0].data.decode("utf-8"))
    else:
        print("Can not recognize.")

    make_qr_code("make_qr_code", "qrcode.png")
    results = decode_qr_code("qrcode.png")
    if len(results):
        print(results[0].data.decode("utf-8"))
    else:
        print("Can not recognize.")

    make_qr_code_with_icon("https://blog.csdn.net/Zhipeng_Hou", "icon.jpg", "qrcode.png")
    results = decode_qr_code("qrcode.png")
    if len(results):
        print(results[0].data.decode("utf-8"))
    else:
        print("Can not recognize.")


一点解释

能继续往下看,说明你还是一个不看到结尾不“死心”的人啊,为你的好学点赞。

关于二维码的具体知识,请你移步到其他的博客,或者想要具体的了解二维码的标准,麻烦你去下载国标详细的阅读。

关于这里个包的安装其实直接pip就行,不过推荐使用下面在安装包的同时安装一些依赖的方式:

pip install qrcode[pil]
pip install pyzbar[scripts]

关于生成QR Code的三个函数,分别名为:make_qr_code_easy,make_qr_code,make_qr_code_with_icon,满足三种不同的需求,第一个easy版本,能够用最少的几句话产生一个QR Code,第二个函数使用了较为详细的参数去指定生成的QR Code的具体参数,下面我会大概解释一下这些参数,(如果英语还凑活)推荐可以去 qrcode 这个包的官网看看他的具体文档,会比我这个一知半解的小白解释的好多了。最后一个函数是将给定的一张图片放在生成好的的QR Code中,来模拟很多现实情况中的二维码。操作都很简单,只不过是将给定图片缩小为原来的 1/4, 而下面的 3/8 是因为计算放置中心图片的左上角起点得到的(稍微说明下,QR Code的宽的中心是 4/8, 中间图片的宽为 1/4, 那么一半是 1/8,所以左边起点是 3/8)。值得注意的一点是,这里最好使用较高的错误矫正率,这样才不会影响到本身的数据信息,因为中心的图像遮挡了一部分QR Code。

  • version 参数是一个从1 到 40 的整数,这个参数控制了QR code 的版本号,最小的是1,此时其为一个21 * 21 的矩阵。如果设置为 None 同时在下面使用了 fit 参数那么算法会自动判断QR Code的大小,并且决定版本号
  • fill_color 以及 back_color 这两个参数,在使用默认图片格式构造时,能够 QR Code的背景色以及数据点的颜色
  • error_correction 控制QR Code的错误矫正率,当然越高的错误矫正率,Code也就越鲁棒,不担心部分损毁;同时,较高的错误矫正率会使得可存储的讯息量下降, 下面给出了可用的常量参数:
    • ERROR_CORRECT_L
      至多能够矫正7%的错误。
    • ERROR_CORRECT_M (default)
      至多能够矫正15%的错误。
    • ERROR_CORRECT_Q
      至多能够矫正25%的错误。
    • ERROR_CORRECT_H.
      至多能够矫正30%的错误。
  • box_size 控制QR Code中每一个小的“box”中能够有几个像素。
  • border 控制QR Code的空白边距大小,默认值为4。

关于读取QR Code 的函数,调用是不是非常的简单,一句话就能搞定,这个decode方法可以接受由PIL.Image读入的图片对象,也可以接受由CV读入的ndarray对象,可以看看pyzbar文档写的非常的清楚。
注意这个函数返回的结果是一个包含很多decoded对象的列表,因为这个包同时可以解析条形码和QR Code。这就是为何我们会传入一个symbols来限制只识别QR Code。
这个decoded对象的形式如下:

[
    Decoded(
        data=b'Thalassiodracon', type='QRCODE',
        rect=Rect(left=27, top=27, width=145, height=145),
        polygon=[
            Point(x=27, y=27), Point(x=27, y=172), Point(x=172, y=172),
            Point(x=172, y=27)
        ]
    )
]

因此通过访问 data 域,我们就可以拿到编码后的byte数组,再经过合适的码值解码后就能拿到str对象了。


最后给出我产生的一个二维码,打开微信扫一扫来试验一下吧~
快行动起来,加密你想表达的内容,用高大上的方式,发送给她,他,它 XD!

在这里插入图片描述

  • 10
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值