QR Code

Quick Response Code

用某种特定的几何图形按一定规律在平面(二维方向上)分布的、黑白相间的、记录数据符号信息的图形。

功能

  • 信息获取
  • 网站跳转
  • 广告推送
  • 防伪溯源
  • 账号登录
  • 手机支付

矩阵式

在这里插入图片描述

位置探测图形 协助扫描软件定位 QR 码并转换坐标系。

校正图形 用于进一步校正坐标系。

定位图形 用于指示标识密度和确定坐标系。

格式信息 存放一些格式化数据的信息。

版本信息 规定二维码的规格。

数据和纠错码 存储实际数据以及用于纠错码字。

位置探测图形分隔符 区分功能图形和编码区域。

蒙版图案 解决大面积的空白或黑块的情况。

Python 生成 QR Code

qrcode

pip install qrcode, Image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import qrcode

# 创建QRCode对象
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=40,
border=4
)
# 添加数据
qr.add_data('https://www.baidu.com')
# 填充数据
qr.make(fit=True)
# 生成图片
img = qr.make_image(fill_color="black", back_color="white")
添加LOGO图片
1
2
3
4
5
6
7
8
9
10
from PIL import Image

# 转换成RGBA格式
img = img.convert('RGBA')
ico = Image.open('favicon.png') # 你本地的图片
# 修改图片大小
ico = ico.resize((int(img.size[0]/3),int(img.size[1]/3)), Image.ANTIALIAS)
ico = ico.convert('RGBA')
img_center_axis = (int((img.size[0]-ico.size[0])/2),int((img.size[1]-ico.size[1])/2))
img.paste(ico, img_center_axis, ico)
预览图片
1
2
3
4
5
6
7
from matplotlib import pyplot as plt

# 预览图片
plt.imshow(img)
plt.show()
# 保存图片
# img.save('baidu.png')
带个性化背景图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import qrcode
from PIL import Image
from matplotlib import pyplot as plt


whiteRGBA = (255,255,255,255) # 白色RGB值
blackRGBA = (0,0,0,255) # 黑色RGB值

class GenerateQRCode(object):
def __init__(self, background_map, version=5, error_correction=qrcode.ERROR_CORRECT_H, box_size=8, border=2):
self.version = version # 版本信息
self.error_correction = error_correction # 容错率
self.box_size = box_size # 二维码位置确定的点数
self.border = border # 边框
self.background_map = background_map # 背景图

def __transparent_back(self,image):
"""白色背景透明设置"""
img = image.convert('RGBA')
W, H = img.size
color_0 = whiteRGBA # 要替换的颜色
for h in range(H):
for w in range(W):
dot = (w,h)
color_1 = img.getpixel(dot)
if color_1 == color_0:
color_1 = color_1[:-1] + (0,)
img.putpixel(dot,color_1)
return img

def __position(self,coordinate):
"""计算二维码黑点白点位置"""
Tlist = list()
Flist = list()
rnum = int(self.box_size/(self.box_size/2))
clen = len(coordinate)
numy = 0
for y in coordinate:
if self.border - 1 < numy < self.box_size + self.border:
numx = 0
for x in y:
if self.box_size + self.border <= numx < clen - (self.box_size + self.border):
if x == True:
# 计算出坐标位置
wx = int(numx*self.box_size) + rnum
hy = int(numy*self.box_size) + rnum
Tlist.append((wx,hy))
elif x == False:
wx = int(numx*self.box_size) + rnum
hy = int(numy*self.box_size) + rnum
Flist.append((wx,hy))
numx += 1
elif self.box_size + self.border <= numy < clen - (self.box_size + self.border):
numx = 0
for x in y:
if self.border - 1 < numx < clen - self.border:
if x == True:
wx = int(numx*self.box_size) + rnum
hy = int(numy*self.box_size) + rnum
Tlist.append((wx,hy))
else:
wx = int(numx*self.box_size) + rnum
hy = int(numy*self.box_size) + rnum
Flist.append((wx,hy))
numx += 1
elif clen - (self.box_size + self.border) <= numy < clen - self.border:
numx = 0
for x in y:
if self.box_size + self.border <= numx < clen - self.border :
if x == True:
wx = int(numx*self.box_size) + rnum
hy = int(numy*self.box_size) + rnum
Tlist.append((wx,hy))
elif x == False:
wx = int(numx*self.box_size) + rnum
hy = int(numy*self.box_size) + rnum
Flist.append((wx,hy))
numx += 1
numy += 1
return Tlist,Flist

def Qrcode(self, txt):
"""生成二维码"""
qr = qrcode.QRCode(
version = self.version,
error_correction = self.error_correction,
box_size = self.box_size,
border = self.border,
)
qr.add_data(txt)
qr.make(fit=True)
# 获取二维码矩阵
coordinate = qr.get_matrix()
# 获取生成的二维码大小
qrimg = qr.make_image()
qrimg = self.__transparent_back(qrimg)
w, h = qrimg.size
# 打开背景图
b_map = Image.open(self.background_map)
# 设置背景图大小
b_map_image = b_map.resize((w, h), Image.ANTIALIAS)
# 获取黑点和白点的列表
(Tlist, Flist) = self.__position(coordinate)
'''
1、把需要缩小的黑色块变成白色
2、画出黑色的小块
3、把图片白色透明
4、二维码图和背景图合并
5、画出白色的小方块
'''

rnum = int(self.box_size/(self.box_size/2))
for n in Tlist:
for m in range(self.box_size + 1):
for m1 in range(self.box_size + 1):
qrimg.putpixel((n[0]-rnum + m1, n[1]-rnum + m),(255,255,255,255))
for p in range(rnum + 2):
for p1 in range(rnum + 2):
qrimg.putpixel((n[0] + p1, n[1]+p),(0,0,0,255))

image = self.__transparent_back(qrimg)
for n1 in Flist:
for p in range(rnum + 2):
for p1 in range(rnum + 2):
image.putpixel((n1[0] + p1, n1[1]+p),(255,255,255,255))
# 保存图片
b_map_image.paste(image, (0, 0), image)
plt.imshow(b_map_image)
plt.show()
# b_map_image.save(save_file, quality=100)

if __name__ == "__main__":
gqrc = GenerateQRCode(background_map='background.jpg')
gqrc.Qrcode("http://wwww.baidu.com")

qrcode · PyPI