今日笔者的公司因为二维码内容为hex字符串,并且内容过长,生成码后密度过大,导致终端扫码摄像头很难识别成功
现借用weapp-qrcode库以及一串hex字符串来说明压缩减半,以及如何将减半的数据传入库来生成码
长度压缩
首先我们有如下hex字符串
let str = '33496AA448F500E87D3F41EF41AB49C4C0047BC419BBA1FB1EEA5D80B6E181D6D39D9C'
java的同事说用byte[]处理,但js无这个接口去直接处理,经过与写c的同事讨论算法,以及下文观察库的源码,发现可以算出unicode值数组,直接放入库中生成码
压缩函数
function strtouint8array(str){
let a = []
let b = (a) => {
if(a >= 48 && a <= 57){
a = a - 48
}else if(a >= 65 && a <= 70){
a = a - 65 + 10
}
return a
}
for(let i = 0; i < str.length / 2; i += 1){
let [c, d] = str.substr(i * 2, 2),
[e, f] = [c.charCodeAt(), d.charCodeAt()] // hexString -> unicode
a[i] = b(e) * 16 + b(f) // unicode压缩算法
}
return a // 示例库修改源码后接受的为array
}
修改库生成码
在github查看weapp-qrcode库的说明,发现只能接收string来生成图片
笔者通过压缩后的unicode -> string再放入库中,生成的码依旧存在问题
通过观察库的源码,笔者发现其实库在接收string后,有个utf16to8的操作,并且在生成码之前,向QRBitBuffer中写入数据时,使用了类似的方法处理了string,并且使用了生成的unicode数组生成码
库源码示例:
//index.js 第8行
// support Chinese
function utf16to8 (str) {
var out, i, len, c
out = ''
len = str.length
for (i = 0; i < len; i++) {
c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
}
//qrcode.js 第35行
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength : function(buffer) {
return this.data.length;
},
write : function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data.charCodeAt(i), 8);
}
}
};
由于生成unicode过程在上文中,我们自己处理过
,所以我们可以不使用库的方法,直接跳过库中utf16to8与转换成unicode的过程
,并且将数据丢进去
所以我们可以将库修改为
//index.js 第8行
// support Chinese
function utf16to8 (str) {
return str
}
//qrcode.js 第35行
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength : function(buffer) {
return this.data.length;
},
write : function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data[i], 8);
}
}
};
修改好之后,在此处命令行执行
npm insall // 安装打包的依赖
npm run build // 构建文件
构建完后使用dist目录下的文件,并且在库的text接口传入压缩后unicode生成的array即可
在此感谢写c的同事@ 程淼
参考文档
版权属于:谁把年华错落成诗 所有,转载请注明出处!
本文链接:https://blog.pomears.com/archives/40.html
如果博客部分链接出现404,请留言或者联系博主修复。