二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
github 上的官网:
https://github.com/lincolnloop/python-qrcode#advanced-usage
CMD 模式下,安装 qrcode 模块
python -m pip install requests
再在 python 中导入 qrcode 模块。
import qrcode
最简单的写法:
import qrcode
data = "https://www.baidu.com" # data 可以是链接,也可以是普通字符串。
erweima = qrcode.make( data )
print( erweima ) #
erweima.save("1.png") # 保存图片。其实利用了PIL对象的 save 方法
qrcode 对象可以通过 make 方法生成 data 数据对应的二维码图片,是一个 PIL 的图形对象。
生成的二维码如下:
微信或者手机浏览器扫描该二维码,会跳转到百度页面。
本质而言,扫二维码就是得到内容,而不会跳转什么页面。微信或者手机浏览器器会跳转,是因为它们添加了如果扫描二维码结果是url就自动跳转的代码造成的。
也可以这样:
import os, qrcode
data = "https://www.baidu.com"
erweima = qrcode.make( data )
with open('1.png', 'wb') as f: # 利用 os 模块的open方法存储图片
erweima.save(f)
创建QRCode对象
add_data() 添加数据
make_image() 创建二维码(返回im类型的图片对象。可以在这里更改二维码的颜色)
自动打开图片,im.show() ; 或者保存二维码到指定位置。
简化版本:
import qrcode,os
data = "https://www.baidu.com" # 二维码数据
ewm = qrcode.QRCode() # 创建QRCode对象,一切采用默认值
ewm.add_data(data) # 添加数据
ewm_img = ewm.make_image() # 生成二维码图像
ewm_img.show() # 直接显示图像
with open("test_qr.jpg","wb") as f: # 保存图像到指定位置
ewm_img.save(f)
扩展版本:
import qrcode,os
# 设置二维码的数据
data = "https://www.baidu.com"
# 创建QRCode对象
ewm = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
# 添加数据到二维码中
ewm.add_data(data=data)
# 更改二维码的颜色,默认是黑色
ewm.make(fit=True)
ewm_img = ewm.make_image(fill_color="#ff3300", back_color="white")
# 显示二维码
ewm_img.show()
with open("test_qr.jpg","wb") as f: # 保存图像到指定位置
ewm_img.save(f)
QRCode 对象参数说明:
version: 一个整数,范围为1到40,用来控制二维码的大小(最小值是1,是个21×21的矩阵),如果想让程序自动生成,将值设置为 None 并使用 make方法的fit=True 参数即可。
error_correction: 二维码的错误容许率,可以选择4个常量:
ERROR_CORRECT_L: 7%以下的错误会被纠正
ERROR_CORRECT_M :15%以下的错误会被纠正【默认值】
ERROR_CORRECT_Q :25 %以下的错误会被纠正
ERROR_CORRECT_H: 30%以下的错误会被纠正
boxsize: 二维码每个点(方块)中的像素个数
border: 二维码到图片边框的小格子数,默认为4,而且相关规定最小为4
方法说明:
add_data(data,optimize=20):添加要转换的数据到data
参数;如果使用了optimize
优化参数,数据将被拆分为多个块来进行优化,以找到一个长度至少为这个值的足够简洁的方式来生成二维码。设置为“0”以避免优化。
make(fit=True):当fit
参数为真或者QRCode 对象没有给出version
参数时,将会调用best_fit
方法来找到适合数据的最小尺寸。如果QRCode 对象没有设置mask_pattern
,将会调用best_mask_pattern
方法来找到找到最有效的掩模图案。最后将这些数据传递给makeImpl
方法来生成二维码。与qrcode
本体的make
方法不一样的是,这个方法没有任何返回值。
make_image( fill_color=None, back_color=None,image_factory=None ):创建二维码的图像并返回,默认为 PIL 图像。颜色值可以是单词,也可以是 #RRGGBB 模式。一般就用前面的两个参数,后面这个默认吧,不用搞那么复杂。
其他方法:
clear:清空数据
get_matrix:返回二维码数组。
print_ascii(out=None, tty=False, invert=False):这个方法用字符画的形式来输出二维码,但是扫的时候一般都扫不出来,很多时候看上去是乱的,也就看看样子用。
import qrcode,os
# 创建QRCode对象
ewm = qrcode.QRCode()
# 设置二维码数据, 并添加到二维码中
data = "https://www.baidu.com"
ewm.add_data(data=data)
ewm.make(fit=True)
# ewm.clear() # 清空数据
ewm_list = ewm.get_matrix() # 获取二维码数组
# 更改二维码的颜色,默认是黑色
ewm_img = ewm.make_image(fill_color="#ff3300", back_color="white")
# 打印字符二维码
ewm.print_ascii() # 根本扫不出来,也就是看看样子。
# 打印二维码数组
print(ewm_list)
# 显示二维码
ewm_img.show() # 如果数据被clear了,会有个二维码,扫它什么都不会发生
简单来讲,就是用小图标直接贴在二维码中。虽然二维码被盖住了一部分,但是因为二维码有一个容错率,所以依然可以扫出来。因此,不建议图标太大,太大了二维码容错率就不行了。
所以,二维码中带图标,一般要设置高容错率( ERROR_CORRECT_H )。
经过别人测试,自己丈量,小图片是二维码图片宽高的 六分之一最合适。
一般情况是把图标放入二维码中的正中间:
绿色块的左上角 x 坐标是 (二维码图片宽 - 图标宽) /2 ,y 坐标同理推得。
所以整体思路是:
先获取二维码,并得到它的宽高;
利用二维码宽高,计算出图标宽高;
利用PIL 的 Image.open 方法,打开图标图片,并进行缩放到适当大小。
把图标“粘贴”进入二维码:利用 PIL 对象的 paste 粘贴方法
把整合的图片保存下来:利用 PIL对象的save 方法。
举例代码:实现准备好一个图标文件,正方形的。我这里是 girl.jpg 文件。
# -*- coding:utf-8 -*-
import os , qrcode
from PIL import Image
import qrcode,os
# 创建QRCode对象
ewm = qrcode.QRCode(
version=5,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=4,
)
# 设置二维码数据, 并添加到二维码中
data = "https://www.baidu.com"
ewm.add_data(data=data)
# 更改二维码的颜色,默认是黑色。得到的结果是 PIL 图像对象
ewm.make(fit=True) # 让二维码得到一个适合的大小值。
ewm_img = ewm.make_image(fill_color="#ff3300", back_color="white")
# 获取二维码大小:宽,高
ewm_size = ewm_img.size
ewm_size_w ,ewm_size_h = ewm_size
# 打开图标文件,并获取图标的大小,重新设定图标大小
# 这里设置icon宽高为二维码的 6分之一。
s = 6
icon = Image.open("girl.png")
# 设置小图标的大小,缩放的时候尺寸必须是整数,否则报错
icon_w,icon_h = int(ewm_size_w/s) ,int(ewm_size_h/s)
icon_small = icon.resize( (icon_w ,icon_h) ,Image.ANTIALIAS) # Image.ANTIALIAS 画面平滑缩放
# 获取粘贴小图标的坐标,必须整数,否则粘贴的时候,报错
icon_x, icon_y = int( (ewm_size_w-icon_w)/2 ), int( (ewm_size_h-icon_h)/2)
# 把图标“粘贴”到二维码上正中间。
ewm_img.paste( icon_small,(icon_x,icon_y) )
# 显示二维码
ewm_img.show() # 如果数据被clear了,会有个二维码,扫它什么都不会发生
ewm_img.save("girl_ewm.jpg")
这里用到了 PIL 的 Image 对象。用到了它的 open() , resize() , paste() 方法。这里就不详细说它们了,具体看注释,比较简单。
有机会再写一篇 PIL 的笔记。最终效果如图:girl 的原图奉上~