二维码生成和解析
二维码生成和解析
简介
二维码(2-Dimensional Bar Code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。
它是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图案表示二进制数据,被设备扫描后可获取其中所包含的信息。
一维条码的宽度记载着数据,而其长度没有记载数据。二维条码的长度、宽度均记载着数据。
二维条码有一维条码没有的“定位点”和“容错机制”。容错机制在即使没有辨识到全部的条码、或是说条码有污损时,也可以正确地还原条码上的信息。
生成二维码
python 可以使用 qrcode 来生成二维码,qrcode默认使用PIL库用于生成图像
pip install pillow
pip install qrcode
简单示例,生成包含xiaobeike信息的二维码:
import qrcode
#添加二维码信息
img = qrcode.make('xiaobeike')
print(type(img))
# 保存图片
img.save("test2.png")
<class 'qrcode.image.pil.PilImage'>
常用方法
add_data(str,optimize=20):添加要转换的文字到data参数;
如果使用了optimize优化参数,数据将被拆分为多个块来进行优化,以找到一个长度至少为这个值的足够简洁的方式来生成二维码。
make(fit=True): 当fit参数为真或者没有给出version参数时,将会调用best_fit方法来找到适合数据的最小尺寸。
make_image(fill_color=None, back_color=None,image_factory=None): 创建二维码的图像并返回,默认为 PIL 图像
#生成二维码的相关参数
- version:一个1 到40之间的整数,用于控制 QR 码的大小(最小的版本1是一个21x21矩阵,最大版本为177x177)
- error_correction:用于二维码的纠错。qrcode 包中提供了以下四个常量:
- ERROR_CORRECT_L 大约可以纠正 7% 或更少的错误。
- ERROR_CORRECT_M (默认)大约 15% 或更少的错误可以被纠正。
- ERROR_CORRECT_Q 大约 25% 或更少的错误可以被纠正。
- ERROR_CORRECT_H 大约可以纠正 30% 或更少的错误。
- box_size:控制二维码的每个“盒子”有多少像素,默认为10。
- border:控制边框应该有多少个框厚(默认为 4,这是根据规范的最小值)
一般情况生成二维码的步骤
创建QRCode对象
add_data()添加数据
make_image()创建二维码(返回im类型的图片对象)
自动打开图片,im.show()
import qrcode
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
data = "xiaobeike"
qr.add_data(data)
qr.make(fit=True)
# fill_color和back_color分别控制前景颜色和背景颜色,支持输入RGB色,注意颜色更改可能会导致二维码扫描识别失败
img = qr.make_image(fill_color=( 213 , 143 , 1 ), back_color="lightblue")
img.save("test2.png")
其他样式二维码
https://blog.51cto.com/luohenyueji/5971314
图像样式 要将样式应用于QRCode,可以使用StyledPilImage。
一个可选的module_drawers参数来控制二维码的形状,
一个可选的color_mask参数来改变二维码的颜色,
一个可选的embeded_image_path参数来嵌入图像
import qrcode
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import RoundedModuleDrawer,SquareModuleDrawer
from qrcode.image.styles.colormasks import RadialGradiantColorMask,SquareGradiantColorMask
# 纠错设置为高
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H)
# 如果想扫描二维码后跳转到网页,需要添加https://
qr.add_data('https://www.baidu.com')
# 修改二维码形状
img_1 = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer())
# 修改二维码颜色
img_2 = qr.make_image(image_factory=StyledPilImage, color_mask=SquareGradiantColorMask())
# 嵌入图像
img_3 = qr.make_image(image_factory=StyledPilImage, embeded_image_path="lena.jpg")
# 嵌入图像
img_4 = qr.make_image(image_factory=StyledPilImage, module_drawer=SquareModuleDrawer(), color_mask=RadialGradiantColorMask(), embeded_image_path="lena.jpg")
彩色二维码示例
import qrcode
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import CircleModuleDrawer, GappedSquareModuleDrawer, HorizontalBarsDrawer, \
RoundedModuleDrawer, SquareModuleDrawer, SquareModuleDrawer, VerticalBarsDrawer
from qrcode.image.styles.colormasks import RadialGradiantColorMask, SquareGradiantColorMask
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
data = "xiaobeike"
qr.add_data(data)
qr.make(fit=True)
# fill_color 前景颜色 支持RGB
# back_color 背景颜色,支持RGB
img = qr.make_image(fill_color=(0, 0, 0),
back_color="lightblue")
img.save("test2.png")
img_1 = qr.make_image(image_factory=StyledPilImage,
module_drawer=RoundedModuleDrawer())
img_1.save("img_1.png")
# 修改二维码颜色
img_2 = qr.make_image(image_factory=StyledPilImage,
color_mask=SquareGradiantColorMask())
img_2.save("img_2.png")
img_3 = qr.make_image(image_factory=StyledPilImage,
embeded_image_path="test.jpg")
img_3.save("img_3.png")
# 嵌入图像
img_4 = qr.make_image(image_factory=StyledPilImage,
module_drawer=CircleModuleDrawer(),
color_mask=RadialGradiantColorMask())
img_4.save("img_4.png")
pyzbar解析二维码
解析二维码常用的模式是pyzbar模块,opencv
pip install pyzbar
# pyzbar 的相关依赖比较麻烦,可以直接使用下面opencv解码,同时含有c++版本
import cv2
import pyzbar.pyzbar as pyzbar
def decodeDisplay(image):
barcodes = pyzbar.decode(image)
for barcode in barcodes:
# 提取二维码的边界框的位置
# 画出图像中条形码的边界框
(x, y, w, h) = barcode.rect
cv2.rectangle(image, (x, y), (x + w, y + h), (225, 225, 225), 2)
# 提取二维码数据为字节对象,所以如果我们想在输出图像上
# 画出来,就需要先将它转换成字符串
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
# 绘出图像上条形码的数据和条形码类型
text = "{} ({})".format(barcodeData, barcodeType)
cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
.5, (225, 225, 225), 2)
cv2.imshow("img",image)
# 向终端打印条形码数据和条形码类型
print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))
return image
img=cv2.imread("../../test2.png")
decodeDisplay(img)
opencv识别解析二维码
OpenCV3.4.4以上开始支持二维码识别和解析自带QRCodeDetector
import cv2
qrcode=cv2.QRCodeDetector()
img=cv2.imread("temp/temp.jpg")
points = qrcode.detect(img)
# img为输入图像,灰度或者彩色图像
# points输出得到的二维码四个点的坐标信息;
straight_qrcode = qrcode.decode(img, points)
# img为输入图像,灰度或者彩色图像
# points是二维码ROI最小外接矩形顶点坐标
# straight_qrcode输出的是二维码区域ROI图像信息 返回的二维码utf-8字符串
result, points, code = qrcode.detectAndDecode(img)
# img为输入图像,灰度或者彩色图像
# result就是解码后的内容
# points是二维码轮廓的四个角,从左上角顺时针转的
# 第三个code是二维码的原始排列,也就是每个点是0还是255的一个矩阵.白色是255,黑色是0.
参考资料
https://www.cnblogs.com/syh6324/p/9497135.html 二维码生成
https://blog.csdn.net/zzx188891020/article/details/106189452 opencv
https://www.cnblogs.com/nthforsth/p/12290779.html 二维码生成
https://blog.csdn.net/weixin_63357306/article/details/132830563 C++
https://blog.csdn.net/u011021773/article/details/107114080/ C++实现解码