【科普文】二维码的[生成]和[扫码]

做者:孙辉,美团金融前端团队成员。15年毕业加入美团,相信技术,更相信技术只是大千世界里知识的一种,我的博客: sunyuhui.comhtml

最近这段时间,团队在作的业务主要和二维码相关,在作的过程当中,发现不论是本身仍是团队里其余同窗,都对二维码自己了解甚少,所以本身调研了一番,在团队内部作了一次分享,在这里整理出来。前端

有意思的是以前在作业务时,QA跑过来问我一个问题:jquery

我两次进入同一个页面,发现图片不同,是否是有问题啊?git

我当时很庆幸本身在作项目以前了解了一些二维码相关的东西,因此我问他:github

你两次扫码的结果是同样的吗?shell

备注:本文涉及到的二维码原理相对粗浅,只能当作二维码的科普文,如有心对二维码生成和扫码原理有深刻研究,请出门左转~canvas

二维码的生成

二维码的结构

为了让你们先直观了解二维码的结构,建议你们先去QR Code Generater,在左侧的地址栏里持续输入不一样的内容(随便敲,使劲敲),在二维码图片的变动过程当中,仔细观察图片,看图片的变化是否是有什么规律。bash

这时候你内心应该大体有谱了,二维码对你来讲再也不只是混沌的黑白图片,如今咱们来介绍下二维码的结构微信



总体分为功能区编码区,功能区主要用于定位,编码区则是真正存储数据的。函数

有几个地方须要注意:

  1. 二维码全部的模块中,储存的并不都是咱们须要的信息,甚至只有一小部分才是。在上面的图中,只有数据和纠错码字中的数据才是咱们实际想存储的数据。
  2. 版本信息:二维码一共有40个版本,不一样版本的区别主要是存储数据的模块的多少(每一块黑/白块就是一个模块),模块数量遵循: moduleCount = 21 + (n-1)×4,好比:版本1的模块数量是21*21,版本40的模块数量为: 21 + (40-1)×4 = 177。

二维码是如何生成的?

那上面的二维码究竟是怎么一步步生成的呢?



上面的图中,详细标注出了二维码的各个结构生成的顺序。左边的流程图是绘制的顺序,右边的图表示绘制到这个流程时已经绘制出来的图形。好比,绘制到【定位图形】这一步时,整个二维码就已经有了左上角、右上角、左小角、链接这三者的横竖两条定位标志以及右下方的校订标志

添加【掩码图案】这个阶段时,整个二维码其实已经绘制完成了,可是若是只是按照实际的信息来绘制,可能会致使页面上有一大片黑色或者一大片白色,而不是咱们如今看到的黑白交叉的图形,这样会致使扫码时识别困难。因此在这一步会再作一步操做:从已有的模板中(模板的黑白是交叉的)选一个,来和生成的二维码图形作异或操做,其中异或操做就是JavaScript中的^运算符

其实在整个生成过程当中,我最好奇的是这些黑白色是怎么生成的(恩,我相信你也是这样的 ^-^ )。

如今咱们以 jquery-qrcode 为例,看下源码

options    = $.extend( {}, {
    render                : "canvas",
    width                : 256,
    height                : 256,
    typeNumber        : -1,
    correctLevel        : QRErrorCorrectLevel.H,
    background      : "#ffffff",
    foreground      : "#000000"
}, options);复制代码

这里是生成二维码时的一些参数,能够看到参数里有个background属性和foreground属性,分别为白色黑色,咦?这么巧?

继续看

// draw in the canvas
for( var row = 0; row < qrcode.getModuleCount(); row++ ){
    for( var col = 0; col < qrcode.getModuleCount(); col++ ){
        ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background;
        var w = (Math.ceil((col+1)*tileW) - Math.floor(col*tileW));
        var h = (Math.ceil((row+1)*tileW) - Math.floor(row*tileW));
        ctx.fillRect(Math.round(col*tileW),Math.round(row*tileH), w, h);  
    }    
}复制代码

这里就是二层循环,用来绘制二维码的内容(二维码是矩形,因此两层循环),其中有行代码鹤立鸡群,立马引发了个人注意:

ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background;

isDark函数是干啥的?咱们去 源码 瞅瞅,而后就能发现,这个函数其实返回的就是二维码里这个位置上的二进制数据,从 这篇文章 里咱们知道二维码生成过程当中,会把全部信息都转换成二进制,因此二维码内容上的数据不是0就是1,那么在isDark函数里,咱们发现,若是位置上的数据是1,就使用白色,若是数据是0,就使用黑色

恩, 这时候就知道为啥二维码是黑白的了吧。

生成二维码时的几个问题

1. 二维码只能是黑白的吗?

源码在手,天下我有

因此让咱们来尝试着生成彩色的二维码吧!

咱们把生成二维码的foreground参数和background参数修改一下,

options = $.extend( {}, {
render : "canvas",
width : 256,
height : 256,
typeNumber : -1,
correctLevel : QRErrorCorrectLevel.H,
background : "#f00", //改为红色
foreground : "#0f0" //改为绿色
}, options);

恩,是的,咱们生成了一个大红大绿的二维码。。。。。绿色对应原来的白色,红色对应原来的黑色。(我打赌,你以前确定没有见过这么艳的二维码 ~



2. 一样的内容生成的二维码是不一样的吗?

不是相同的,就如同咱们开篇QA提到的那样,不过扫码后获得的结果是同样的。不一样的缘由是因为在具体生成黑白块时,是按照必定规律随机放置在图片中的。

3. 既然能够生成彩色的,为啥咱们日常见到的二维码都是黑白的?

嗯,好问题,这个问题咱们稍后解答~

二维码的[扫码]

你们日常在用各类APP扫码的时候,主要是付款、取(电影)票、添加微信好友等一些场景

咱们能明显感觉到的只是那的一声,那么在扫码的时候究竟发生了什么呢?我最近在作的业务中就有一环是【扫码】,因此我研究了一下。总体流程图是这样的



总的来讲,扫码的流程就是两步:

  1. 获取二维码图片信息
  2. 对图片信息作相应处理

这时候你再回想下本身在微信、美团、点评等APP里使用扫码功能时出现的不一样状况,恩,你应该明白了。。

也许你已经习惯了每次扫码都会跳转到一个新页面,又或者你日常根本没注意这种事,但并不老是 扫码后跳转到一个连接 这么简单,而是对扫码返回的信息作不一样处理。跳转到一个连接 只是其中一种方式。

在生成二维码时,咱们提过到,二维码的生成过程,就是一个对信息加密的过程,那么【扫码】这个过程呢?其实就是一个解密的过程。具体怎么去解密的,能够去读一下Zxing的源码

扫码时的几个问题

拍照用的摄像头和扫码用的摄像头有什么区别?

其实都是调用的手机的摄像头,可是扫码的摄像头由APP控制,具有解析二维码内容的能力。

为啥你们见到的二维码都是黑白的?

即使是从颜值上考虑,彩色的也会更好看,在现在颜值即正义的时代里,不可能有人想不到用彩色的二维码来代替黑白的。

缘由是因为:黑白二维码扫码速度更快,对于手机摄像头来讲,要读取信息,就要获取图片中的两种二进制信息(1和0),在前文已经说过,1表明白色,0表明黑色,黑色的色值是#000000,白色的色值是#ffffff,在全部颜色中,只有黑色和白色的色值差是最大的,对手机来讲,也就更容易区分了,可是若是咱们用其余的两种颜色来代替黑色和白色呢?其实我已经在前文里把彩色二维码给你们展示了,你们能够分别扫一下彩色的二维码和黑白的二维码,应该能明显感受到黑白的更快。

扫码时的速度取决于什么?

这个问题多是不少作二维码相关业务的人关注的事情了,因素也有多方面的。

从二维码的角度:

  1. 二维码的平整度(二维码都放在一个壳子里)
  2. 二维码内容的辨识度(能看到的基本都是黑白的)
  3. 存续的信息量大小(以如今手机的处理能力,这个因素影响很小)

从手机的角度

  1. 不一样的APP针对扫码作的优化措施不同,好比微信就作了不少优化措施。
  2. 摄像头硬件配置

其中二维码的平整度(二维码都放在一个壳子里)这个因素,你们日常在外面吃东西扫二维码付款时,应该均可以看到二维码是放在一个白色的壳子里,我不知道这是否是各大公司有意识的作这件事,也许他们只是想延长二维码的使用寿命,但这个措施确实作的很是好。

ok,到这里就差很少了,但愿看完这篇文章以后,你们对二维码应该有了一些了解,不会像之前同样,二维码对你们来讲只是一张黑白图片。

Done.

最后,团队为了招聘方便,整了个公众号,主要是一些招聘信息,团队信息,全部的技术文章在公众号里也能够看到,对了,若是你想去美团其余团队,咱们也能够帮你内推哦 ~

二维码
二维码

参考:

  1. 二维码的生成细节和原理
相关文章
相关标签/搜索