我们目前开发的AR专用汉明码是7X7的,外围用黑块包围,实际上就是5X5的一个汉明码。
下面简略的说一下汉明码的编码规则:
5X5的汉明码每一行5位,有3位校验位,2位数据位,具体是第1,3,5位是校验位,第2,4位是数据位
5X5的汉明码每一行仅有2个数据位,只能表示4种数据:00,01,10,11 。所以5行一共可以表示4的5次方种数,即1024种
具体免费内容见博文
校验位的计算方法:
5位表示位:D1,D2,D3,D4,D5 ---------第D1,D3,D5位校验位,D2,D4位数据位
校验位的计算方法自行百度吧 ,AR码不同的地方只是当D2,D4=00是为了防止全黑将D1置1即10000
所以,每一行能表示的4种情况分别是:
00:10000
01:10111
10:01001
11:01110
作为AR专用,为了提高识别率防止二维码全黑,规定数据位是00的编码出来后首位改为1,即100000
例如ID为156的汉明码是这样的:
把它分割出每一小块分别表示如下数据:
生成汉明码ID的规则就是在正确方向的前提下(有4个方向)从左到右依次把每一行表示的数据组合起来对应的十进制数就是它的ID
比如上面这个汉明码从第一行到最后一行组合起来就是0010011100即10011100,对应的十进制数是156,所以这个汉明码码的ID就是156。
接下来就是怎么编程去实现这个生成过程了,我用的JAVA,放一些核心部分的代码:
我想实现的功能是:给一个汉明码的ID我就能生成这个ID对应的汉明码,
那么我就用画矩形的函数一个格子一个格子的画呗。
首先画上一个黑边,
然后用1100000000即768跟所给的ID进行与操作 后右移8位,如果是0就在第一行画出 白黑黑黑黑黑,如果是1就画白黑白白白,如果是2就画黑白黑黑白,如果是3就画黑白白白黑
然后用11000000即192跟所给的ID进行与操作 后右移6位,如果是0就在第二行画出 白黑黑黑黑黑,....同上。
然后用110000即48跟所给的ID进行与操作 后右移4位,如果是0就在第三行画出 白黑黑黑黑黑,....同上。
然后用1100即12跟所给的ID进行与操作 后右移2位,如果是0就在第四行画出 白黑黑黑黑黑,....同上。
然后用11即3跟所给的ID进行与操作 后不用移位,如果是0就在第三行画出 白黑黑黑黑黑,....同上。
//-----------------------第一行------------------------------------------//
if ((768&id)==0) {
graphics.fillRect(2*temp, temp, 4*temp, temp);
}
else if (((768&id)>>8)==1) {
graphics.fillRect(2*temp, temp, temp, temp);
}
else if (((768&id)>>8)==2) {
graphics.fillRect(temp, temp, temp, temp);
graphics.fillRect(3*temp, temp, 2*temp, temp);
}
else if (((768&id)>>8)==3) {
graphics.fillRect(temp, temp, temp, temp);
graphics.fillRect(5*temp, temp, temp, temp);
}
//-----------------------第2行------------------------------------------//
if ((192&id)==0) {
graphics.fillRect(2*temp, 2*temp, 4*temp, temp);
}
else if (((192&id)>>6)==1) {
graphics.fillRect(2*temp, 2*temp, temp, temp);
}
else if (((192&id)>>6)==2) {
graphics.fillRect(temp, 2*temp, temp, temp);
graphics.fillRect(3*temp, 2*temp, 2*temp, temp);
}
else if (((192&id)>>6)==3) {
graphics.fillRect(temp, 2*temp, temp, temp);
graphics.fillRect(5*temp, 2*temp, temp, temp);
}
//-----------------------第3行------------------------------------------//
if ((48&id)==0) {
graphics.fillRect(2*temp, 3*temp, 4*temp, temp);
}
else if (((48&id)>>4)==1) {
graphics.fillRect(2*temp, 3*temp, temp, temp);
}
else if (((48&id)>>4)==2) {
graphics.fillRect(temp, 3*temp, temp, temp);
graphics.fillRect(3*temp, 3*temp, 2*temp, temp);
}
else if (((48&id)>>4)==3) {
graphics.fillRect(temp, 3*temp, temp, temp);
graphics.fillRect(5*temp, 3*temp, temp, temp);
}
//-----------------------第4行------------------------------------------//
if ((12&id)==0) {
graphics.fillRect(2*temp, 4*temp, 4*temp, temp);
}
else if (((12&id)>>2)==1) {
graphics.fillRect(2*temp, 4*temp, temp, temp);
}
else if (((12&id)>>2)==2) {
graphics.fillRect(temp, 4*temp, temp, temp);
graphics.fillRect(3*temp, 4*temp, 2*temp, temp);
}
else if (((12&id)>>2)==3) {
graphics.fillRect(temp, 4*temp, temp, temp);
graphics.fillRect(5*temp, 4*temp, temp, temp);
}
//-----------------------第5行------------------------------------------//
if ((3&id)==0) {
graphics.fillRect(2*temp, 5*temp, 4*temp, temp);
}
else if ((3&id)==1) {
graphics.fillRect(2*temp, 5*temp, temp, temp);
}
else if ((3&id)==2) {
graphics.fillRect(temp, 5*temp, temp, temp);
graphics.fillRect(3*temp, 5*temp, 2*temp, temp);
}
else if ((3&id)==3) {
graphics.fillRect(temp, 5*temp, temp, temp);
graphics.fillRect(5*temp, 5*temp, temp, temp);
}
生成图片的函数为:
//-----------------------生成图片函数------------------------------------------//
void createImage(String fileLocation) {
try {
FileOutputStream fos = new FileOutputStream(fileLocation);
BufferedOutputStream bos = new BufferedOutputStream(fos);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(image);
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
最后的效果是这样的
有兴趣的欢迎加我交流!
最后附上AR专用汉明码生成器的程序