大家见过不少带品牌logo的二维码,普通的黑白二维码生成比较容易,那么这种嵌入logo的二维码该如何生成呢?
基本原理
有一种比较简单的方法,就是直接在生成的黑白二维码中间覆盖一层logo. 覆盖一层logo后,必定会影响二维码的纠错能力。为了能从嵌入logo的二维码中还原数据,logo的覆盖面积要控制好。
二维码有如下四种纠错级别:
- ERROR_CORRECT_L:大约<=7%的错误能纠正过来
- ERROR_CORRECT_M:大约<=15%的错误能纠正过来
- ERROR_CORRECT_Q:大约<=25%的错误能纠正过来
- ERROR_CORRECT_H:大约<=30%的错误能纠正过来
当纠错级别越高时,二维码能容纳的数据量就越少。正是因为二维码具有一定的纠错能力,所以在二维码中间覆盖一层logo是没有问题的,只要控制好覆盖面积。
Python实现
Python有个纯Python实现的二维码生成库,叫做qrcode. 其接口使用起来比较简单,所以下面不谈如何使用qrcode库生成二维码,而是介绍如何在生成好的黑白二维码中间覆盖一层logo图片。
覆盖一层logo图片本质上属于图片处理。下面是代码:
def image_center_overlay(background_image, frontend_image, percentage=0.0625):
"""
把frontend_image覆盖到background_image的中间
:param background_image:
:param frontend_image:
:param percentage: frontend_image最多覆盖background_image多大比例
:return:
"""
b_width, b_height = background_image.size
f_width, f_height = frontend_image.size
if f_width * f_height <= b_width * b_height * percentage:
f_image = frontend_image
else:
scale = math.sqrt(b_width * b_height * percentage / (f_width * f_height))
f_width = int(math.floor(f_width * scale))
f_height = int(math.floor(f_height * scale))
f_image = frontend_image.resize((f_width, f_height), resample=Image.ANTIALIAS)
x = int(math.floor((b_width - f_width) / 2))
y = int(math.floor((b_height - f_height) / 2))
new_image = Image.new('RGB', (b_width, b_height), (255, 255, 255))
new_image.paste(background_image, box=(0, 0))
new_image.paste(f_image, box=(x, y))
return new_image
代码中的image均为PIL中的Image对象。上述方法中的percentage是如何确定的呢?其实是二维码纠错率的平方。比如,以ERROR_CORRECT_Q纠错级别生成二维码,那么percentage的值为25% * 25%,也就是0.0625.