[写在前面] 在当今社会中,二维码的使用非常的广泛。当然作为一名充满好奇心又爱装逼的 coder 怎么能不会使用二维码编码自己想表达的内容呢,尤其是用在装逼和找对象上。
一番学习和搜索之后发现,对于使用Java
,JSP
, Android
,JS
编程的小伙伴来说,网上的资料是一箩筐,基本找一找就可以“板砖”了。但是作为拥有众多包的Python
来说,怎么搜来搜去都是非常陈旧的资料,很多都是针对Python2
的代码,而且大多都不能再使用了。除此之外,其中还有很多文章都只有针对Python
生成一个QR Code
的解释和代码,而如何去识别一个二维码的却非常的少。虽然也有,但是不是使用Jpython
去调用Java
中的工具包去识别,就是需要大量的代码去实现。作为一个小白,就希望简单的调用就能达到自己的效果就好。因此,在搜索了大量博客、网页之后,在pypi上我找到了两个库能够很好的解决问题。
这两个库不仅同时支持Python2
Python3
,而且调用方式非常的简单只需要简单的一两句话就能完事,而且都是pypi
上的包,能够通过pip
进行安装和管理,开源且拥有自己的github,提供有官方文档,可以快速使用。
这两个库分别是:
是不是很迫不及待?话不多说,先上代码。我已经包装好了函数,直接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
ERROR_CORRECT_M (default)
ERROR_CORRECT_Q
ERROR_CORRECT_H.
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!