QR码使用总结
QR码(学名为快速响应矩阵码;Quick Response Code)是二维码的一种,相应的ISO国际标准ISO/IEC 18004,现在互联网上的二维码一般都是QR码。本文主要总结生成QR码(模式2)遇到的几个问题,生成使用开源条码库ZXing。
QR码尺寸问题
问题描述:运营同学需要23px*23px的QR码(不包括边缘留白),一定能实现么?
背景知识:QR码共有40种版本,每个版本都有固定的码元数(码元是指构成QR码的方形的黑白点),从版本1(21码元*21码元)开始,在纵向和横向各自以4码元为单位增加,一直到版本40(177码元*177码元)。QR码的版本越高数据容量也越大,具体能编码字符的容量与字符类型和纠错级别也相关(详情参考ISO/IEC 18004)
解决问题:如果要生成23px*23px的QR码,只有版本1的最小尺寸21px*21px小于23px*23px,版本1的最大数据19byte,假设要编码的数据量小于19byte,使用ZXing生成的QR码边框会有1个像素的留白,可以这样解决留白问题,生成21px*21px像素的二维码,然后放大QR码到23px*23px,测试过双线性差值算法放大后可解码,不过图片效果较差,而使用JDK默认的放大算法图片效果比较好,也可解码(如果是较小版本的QR码放大,最好测试能否解码),到这里基本可以实现。
想说明的是,QR码的最小尺寸公式:21 + 4n(n是对应的版本,公式不包括边框留白),QR码的大小最好还是按照对应版本的整数倍放大,这样不会失真,利于解码,微信公共账号生成的QR码建议是按照43像素的整数倍放大(解码后得到版本是5,21+ 5*4 + 1个像素边框留白)。
再说一下ZXing生成QR码时尺寸的策略,只会按照最小尺寸的整数倍数放大,根据要编码的数据等确定QR码版本(比如5,最小尺寸为21+4*5=41),要生成的QR码为200px*200px,则(200 – 41*4)/2=16,则边框有16px的留白,而生成QR码的输入参数margin并不总是起作用。
QR码的美化
通常有把logo加到QR码中的需求,原理是QR码采用纠错算法生成一系列纠错码字,添加在数据码字序列后,使得符号可以在遇到损坏时不致丢失数据。QR码添加logo后相当于这一块数据损坏,如下代码可实现QR码中心添加logo。
有运营同学需要添加的logo能尽量大,logo的最大值为多少才可以解码呢,QR码的每个版本的每个纠错等级都对应有纠错码字数,一个替代错误需要两个纠错码字来纠正,所以理论上纠错容量小于纠错码字数的一半是可以解码的,具体的纠错码字数查表可知。实际上等于纠错码字的一半时依然有很多扫码客户端无法解码,使用时logo可以再小一点(1/2.8测试结果是个比较理想的系数)。logo的最大宽度,基于ZXing实现如下
ZXing默认支持设置QR码的背景色和前景色的设置,QR码扫描仪是通过红色光的照明捕捉QR码的,如果背景反射红色、前景的颜色为吸收红色的组合,可以读取,具体调整颜色后最好测试是否可以扫码。
QR码的美化可以做的事情比较多,把二维码融入背景图里等,有兴趣的同学可以一块学习。
乱码问题
问题描述:使用ZXing生成带中文的QR码,用其它客户端解码可能会乱码(如微信)或者直接无法解码,用ZXing自己的解码SDK无问题。
问题原因:ZXing会在文本编码前添加一段ECI编码(Extended Channel Interpretation扩展解释),用来标记文本编码的字符集,方便解码,这也是符合QR码标准的,不过在标准里未定义字符集的映射关系,这样ZXing写入的字符集信息不一定能被其它解码器识别,导致无法解码,解决思路是生成QR码时不生成这段ECI编码,解码时依赖程序自动识别。
解决问题:
1. 如果自己维护有ZXing的源码,可以注释掉添加字符集信息的ECI MODE代码(com.google.zxing.qrcode.encoder.Encode)
2. 不修改源码的方法,使用小写(如utf-8)即可避免插入ECI MODE
矢量QR码
矢量QR码适用于印刷高精度的QR码图片,常用的矢量格式有SVG、EPS,常见的绘图程序(如PhotoShop)都支持EPS格式。矢量图文件一般都比较大,而普通的QR码只有两种颜色,再加上EPS的PostScript语法的支持,可以用如下的代码生成一个EPS格式的QR码(比全部描述像素点生成的图片文件要小接近一个数量级)。
附件(ISO/IEC 18004)
(备注:EPS格式的矢量二维码,WORD支持PostScript脚本渲染成图片)
Qart.js
https://github.com/kciter/qart.js
Merges Pictures and QR Codes for Artistic QR Codes.
https://github.com/kazuhikoarase/qrcode-generator