QR code 入门教程(三)
承接上文,我们已经说过了数据编码和纠错码的生成,接下来我们继续下面的步骤
结构化最终的数据
- 所谓的结构化(Structure),说白了就是如何把之前生成的数据排成一个比特流。根据之前内容,我们已经得到了数据流以及纠错码,这些数据目前被放在不同的块(Block)中,如下表
Group Number | Block Number | Data Codewords in the Group | Data Codewords as Integers |
---|---|---|---|
Error Correction Codewords for the Block | |||
Group 1 | Block 1 |
(codeword #1) 01000011 (codeword #2) 01010101 (codeword #3) 01000110 (codeword #4) 10000110 (codeword #5) 01010111 (codeword #6) 00100110 (codeword #7) 01010101 (codeword #8) 11000010 (codeword #9) 01110111 (codeword #10) 00110010 (codeword #11) 00000110 (codeword #12) 00010010 (codeword #13) 00000110 (codeword #14) 01100111 (codeword #15) 00100110 |
Data Codewords from the left, as Integers: 67,85,70,134,87,38,85,194,119,50,6,18,6,103,38 Error Correction Codewords (show how these were calculated): 213 199 11 45 115 247 241 223 229 248 154 117 154 111 86 161 111 39 |
Block 2 | (codeword #16) 11110110 (codeword #17) 11110110 (codeword #18) 01000010 (codeword #19) 00000111 (codeword #20) 01110110 (codeword #21) 10000110 (codeword #22) 11110010 (codeword #23) 00000111 (codeword #24) 00100110 (codeword #25) 01010110 (codeword #26) 00010110 (codeword #27) 11000110 (codeword #28) 11000111 (codeword #29) 10010010 (codeword #30) 00000110 |
Data Codewords from the left, as Integers: 246,246,66,7,118,134,242,7,38,86,22,198,199,146,6 Error Correction Codewords (show how these were calculated): 87 204 96 60 202 182 124 157 200 134 27 129 209 17 163 163 120 133 |
|
Group 2 | Block 1 | (codeword #31) 10110110 (codeword #32) 11100110 (codeword #33) 11110111 (codeword #34) 01110111 (codeword #35) 00110010 (codeword #36) 00000111 (codeword #37) 01110110 (codeword #38) 10000110 (codeword #39) 01010111 (codeword #40) 00100110 (codeword #41) 01010010 (codeword #42) 00000110 (codeword #43) 10000110 (codeword #44) 10010111 (codeword #45) 00110010 (codeword #46) 00000111 |
Data Codewords from the left, as Integers: 182,230,247,119,50,7,118,134,87,38,82,6,134,151,50,7 Error Correction Codewords (show how these were calculated): 148 116 177 212 76 133 75 242 238 76 195 230 189 10 108 240 192 141 |
Block 2 | (codeword #47) 01000110 (codeword #48) 11110111 (codeword #49) 01110110 (codeword #50) 01010110 (codeword #51) 11000010 (codeword #52) 00000110 (codeword #53) 10010111 (codeword #54) 00110010 (codeword #55) 11100000 (codeword #56) 11101100 (codeword #57) 00010001 (codeword #58) 11101100 (codeword #59) 00010001 (codeword #60) 11101100 (codeword #61) 00010001 (codeword #62) 11101100 |
Data Codewords from the left, as Integers: 70,247,118,86,194,6,151,50,16,236,17,236,17,236,17,236 Error Correction Codewords (show how these were calculated): 235 159 5 173 24 147 59 33 106 40 255 172 82 2 131 32 178 236 |
接下来要做的工作就是把这些数据 “安排的明明白白的”。
Step 2 交错插入块
- 这个很好理解,请看 Interleave the Data Codewords 和 Interleave the Error Correction Codewords。这里不再重述。
- 然后把交错后的纠错码放在交错后的数据码字后面,就可以了
Step 3 转化为 2 进制
- 将 Step 2 排列好的数字转为 2 进制。
补零剩余位
- 有些版本的最终信息比特流没法填满整个QR码,对于这种情况,需要在末尾补零。补零的个数请查看 List of Versions and Required Remainder Bits。其实补零的个数也是可以算出来的,以 5-Q 为例,其中数据码字数为 60,纠错码码字数为 72(18*4),共 (72+60)*8 = 1072 个比特,然后再对比下表(下标来自国标),可以知道 5-Q 的数据容量是 1079,那么 1079 - 1072 = 7,需要补 7 个 0.
在矩阵中放置模块
像素和模块的区别。模块就是一块黑的或者白的块,模块由若干像素组成。例如一个 21*21 的模块,像素有可能是 42*42,或者 105*105。
功能图形
+ 位置探测图形(Finder Pattern)。三个块,用于定位
+ 分隔符(Separator)。用于将位置探测图形与其他部分分开的功能图形,全都是浅色模块,宽度为 1.
+ 校正图形(Alignment Pattern)。长得有点像位置探测图形,但是更小更多。
+ 定位图形(Timing Pattern)。深色与浅色模块交错的图像,用于确定符号中模块的坐标。深色模块(Dark module)。干啥用的?确定版本信息?我也不清楚。
Step 1:放置位置探测图形
- 有三个这样的图形,它们的左上角位置为: 左上角(0,0)、左下角(0, (V-1)*4+21-7)、右上角((V-1)*4+21-7,0)。
Step 2:添加分隔符
- 在位置探测图形外面加一圈浅色模块
Step 3:添加校正图形
- 校正图形长得和位置探测图形比较像,其个数与版本有关,可查表 alignment pattern locations table。
Step 4:添加定位图形
- 有两条,垂直一条,水平一条。位于两个finder patterns之间,并且开始和结束都是黑色的块。可以与校正图形重叠,因为它们两的颜色是一致的(多么神奇)
Step 5:添加深色模块和保留预留区域
- 就是一黑点,位置为 (8,4V+9)
- 还要格式信息区域(Format Inoformation Area),具体位置如蓝色区域
- 保留版本信息区域,蓝色位置,一个是6*3,另一个是3*6
Step 6:放置数据比特流
- 从右下角开始,遇到功能图像则跳过,直到一下个可用位置。放置的顺序如下图
- 如果遇到了垂直的那条定位图形,直接下一列开始
- 每次填两列,具体看下图
- 遇到功能图像的时候跳过。
数据掩码
- 数据和功能图形都放进去了,现在加上掩码,这是为了让读取器能够容易的读取数据
- 掩码就是就是对块取反,有八种掩码方案,参看 QR Mask Patterns Explained
选择最好的那种掩码
- 八种掩码,八个结果,对每种结果进行评估取惩罚值最小的那种。
-
惩罚值计算方法:
- The first rule gives the QR code a penalty for each group of five or more same-colored modules in a row (or column).
- The second rule gives the QR code a penalty for each 2x2 area of same-colored modules in the matrix.
- The third rule gives the QR code a large penalty if there are patterns that look similar to the finder patterns.
- The fourth rule gives the QR code a penalty if more than half of the modules are dark or light, with a larger penalty for a larger
difference.
条件 1,遇到=5个一样的块,惩罚值为3,如果在第一个=5的块后颜色还是一样,惩罚值为1。看图说话
条件 2,遇到2*2的块,惩罚值为3。
条件 3,找类似位置探测图像的块,简单的说就是找下面两种,惩罚值为40
-
条件 4,这个条件希望深色和浅色模块要尽量一样多,具体步骤是:
- 计算矩阵中所有模块的数量
- 计算深色模块的占比:(深色模块数 / 总模块数)*100
- 然后向前找5的倍数,向后找5的倍数。例如,占比=43,那么前一个5的倍数是40,后面一个是45
- 计算与 50% 的绝对值差,例如 |45-50| = 5,|40 - 50| = 10。
- 然后除以 5,例如,5/5 = 1, 10/5=2。
- 取小的那个值,然后乘上10,得到惩罚值。例如 1,2中1更小,所有惩罚值是1*10=10。
格式和版本信息
- 最后一步!格式信息包括校正级别和掩码的方案,可查表 Format and Version String Tables,将格式信息填入矩阵,以 110011000101111 为例
- 在(8, 4*V+9),把深色模块给画上
- 版本信息,查Format and Version String Tables,然后按下图位置填上18位的比特流