作者:王子旭
链接:https://zhuanlan.zhihu.com/p/
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2016.7.5 更新:长文多图代码预警,电脑食用效果更佳。
完整版代码已上传 GitHub,后续一些有的没的的代码更新也都在GitHub上(https://github.com/LaytonW/qrcode)
给结尾的几个被自动识别的QR码做了防自动识别。。顺便也检测一下我们这不怎么高的容错率(7%)。要是再被知乎自动识别了。。。(:з」∠)
======================================================================
作为一只程序猿,第一篇文章自然要写hello world,但是呐,我看你们今天这样热情,只写一句hello world就闷声你们又不高兴。刚好最近实习工作在处理QR码,就来薛习一下QR码版本的hello world吧。
-
前期准备
- 背景信息
要想实现一个QR码生成器,我们首先需要了解什么是QR码,QR码有哪些类型,以及QR码是如何工作的。
QR码(Quick Response Code) 是二维码的一种,在正方形二位矩阵内通过黑白标识编码二进制位从而编码数据,最早发明用于日本汽车制造业追踪零部件。QR码现有40个标准版本,4个微型版本。QR码的数据编码方式有四种:
- 数字(Numeric):0-9
- 大写字母和数字(alphanumeric):0-9,A-Z,空格,$,%,*,+,-,.,/,:
- 二进制/字节:通过 ISO/IEC 8859-1 标准编码
- 日本汉字/假名:通过 Shift JISJIS X 0208 标准编码
QR码还有四种容错级别可以选择:
- L(Low):7%的字码可被修正
- M(Medium):15%的字码可被修正
- Q(Quartile):25%的字码可被修正
- H(High):30%的字码可被修正
(Wikipedia: QR code, https://en.wikipedia.org/wiki/QR_code)
(40+4)×4×4=…… ∑(っ °Д °;)っ
讯享网咳。。好,那我们为了读者着想 (←_←),只实现 Version 1-Byte mode-Low error control 的QR码生成就好了嗯。。
好我们继续。
如今QR码随处可见,大家阅码无数可能也发现了一些规律:这些QR码有大有小、有红有绿,有些还有各种装饰,但是它们总有一些部分看起来十分相似,比如三个角落里总有“回”字形的图样。这就要谈到QR码的结构了。
- 结构
除了存储编码的数据,QR码里还含有一些基本标准里钦定的图样来帮助扫描软件快速识别和解码。
(图片来源:Wikipedia:QR码,https://zh.wikipedia.org/wiki/QR%E7%A2%BC)

标准(ISO/IEC 18004)里是这样说的
(图片来源:ISO/IEC 18004: Information – Automatic identification and data capture techniques – QR Code barcode symbology specification)
所以说我们做QR码啊,还是要按照QR标准,按照基本标准来。我没有任何硬点这些图样的意思,它们都是有自己的作用的,我们一个一个说。
-
<ul><li>功能性图样(function patterns):不参与编码数据的区域。</li></ul></li></ul>
讯享网-
讯享网
<ul><li> <ul><li>闷声区(quite zone):标准中规定标准QR码(Ver1-40)四周应有宽4个单位、微型QR码四周应有宽2个单位的区域颜色等效于QR码中白色点(light module),其中不能有图样或标记,以保证QR码清晰可识别。</li><li>定位标识(finder pattern):之前提到的“回”字形标识,位于QR码的左上,右上和左下角,用于协助扫描软件定位QR码并变换坐标系。定位标识可以让QR码在任意角度被扫描,这是一维条形码做不到的。<img class="origin_image zh-lightbox-thumb" src="https://pic1.zhimg.com/24c636d60ebaaf921f8cc65885c4d5b4_b.png" alt="" width="484" />(图片来源:ISO/IEC 18004: <em>Information – Automatic identification and data capture techniques – QR Code barcode symbology specification</em>)</li><li>分隔符(separator):一单位宽的白色点带,位于每个定位标识和编码区域之间用于区分。</li><li>定时标识(timing pattern):一单位宽的黑白交替点带,由黑色起始和结束,用于指示标识密度和确定坐标系。</li><li>校正标识(alignment pattern):只有 Version 2 及以上的QR码有校正标识。校正标识用于进一步校正坐标系。校正标识的数量取决于版本。</li></ul></li><li>编码区域(encoding region):编码数据的区域。 <ul><li>格式信息(format information):存储容错级别和数据掩码,和额外的自身BCH容错码,讲到再展开。</li><li>版本信息(version information):存储版本信息。</li><li>数据及容错字码(data and error correction codewords):存储编码方式,实际编码的数据和数据的RS容错码。</li></ul></li></ul></li></ul>以上就是QR码的通用结构标准了,再来看一看我们要实现的 Version 1 QR码的结构:

(图片来源:ISO/IEC 18004: Information – Automatic identification and data capture techniques – QR Code barcode symbology specification)
分析完了QR码的结构,豁然开朗,这东西也不就这么回事嘛,简单!开始做!(多年以后,当程序猿面对电脑屏幕的时候,将会回想起不懂事的自己立起flag的那个下午)
- 流程
方便的是,标准也规定了将数据编码成QR码的流程:
- 数据分析(data analysis):分析输入数据,根据数据决定要使用的QR码版本、容错级别和编码模式。低版本的QR码无法编码过长的数据,含有非数字字母字符的数据要使用扩展字符编码模式。因为我们只实现 V1-L byte mode QR码,此步略去。
- 编码数据(data encoding):根据选择的编码模式,将输入的字符串转换成比特流,插入模式标识码(mode indicator)和终止标识符(terminator),把比特流切分成八比特的字节,加入填充字节来满足标准的数据字码数要求。
- 计算容错码(error correction coding):对步骤二产生的比特流计算容错码,附在比特流之后。高版本的编码方式可能需要将数据流切分成块(block)再分别进行容错码计算。
- 组织数据(structure final message):根据结构图把步骤三得到的有容错的数据流切分,准备填充。
- 填充(module placement in matrix):把数据和功能性图样根据标准填充到矩阵中。
- 应用数据掩码(data masking):应用标准中的八个数据掩码来变换编码区域的数据,选择最优的掩码应用。讲到再展开。
- 填充格式和版本信息(format and version information):计算格式和版本信息填入矩阵,完成QR码。
简单! ( ̄ε(# ̄)☆╰╮( ̄▽ ̄///) ↓↓↓

-
代码实战
因为程序需要处理矩阵,方便起见在这里先定义坐标系统。以矩阵的左上角为原点,原点坐标定义为(0,0),i 轴向右,坐标 i 对应列;j 轴向下,坐标 j 对应行。于是对于图像中的像素(i,j),有矩阵元素 mat [ j ] [ i ] 与之对应。

新建Python代码文件 qrcode.py,引入需要的库:
# qrcode.py from PIL import Image, ImageDraw
-



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/69411.html