二维码生成和解析

二维码生成和解析

简介

二维码(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++实现解码

posted @ 2023-11-10 14:12  贝壳里的星海  阅读(323)  评论(0编辑  收藏  举报