有个需求:蓝牙要显示二维码,需要得到二维码的位图(点阵图、矩阵图)。
实现思路:
1.获得canvas的二维码图片,要求为64px乘64px
2.获得二维码的图片,然后解析像素数组,获得像素的二进制状态码
3.将二进制状态码转化为byte数组,然后发送给蓝牙。
这里强调一点,draw方法和canvasGetImageData都是异步加载,需要通过promise来做等待处理。
首先,按照网上通用的二维码生成代码实现获得二维码矩阵,使用qrcode.js来获得。
核心代码为draw方法:
/**
* 新增$this参数,传入组件的this,兼容在组件中生成
*/
draw: function (str, canvas, cavW, cavH, $this) {
console.log("draw");
var that = this;
// ecclevel = ecc || ecclevel;
// console.log("ecclevel>>" + ecclevel);
canvas = canvas || _canvas;
if (!canvas) {
console.warn('No canvas provided to draw QR code in!')
return;
}
var size = Math.min(cavW, cavH);
str = that.utf16to8(str); //增加中文显示
var frame = that.getFrame(str),
// 组件中生成qrcode需要绑定this
ctx = wx.createCanvasContext(canvas, $this),
px = (size / (width + 8));
console.log("width>>1>>" + width);
console.log("frame>>" + frame);
console.log("frame.length>>" + frame.length);
var roundedSize = px * (width + 8),
offset = Math.floor((size - roundedSize) / 2);
size = roundedSize;
//ctx.clearRect(0, 0, cavW, cavW);
ctx.setFillStyle('#ffffff')
ctx.fillRect(0, 0, cavW, cavW);
ctx.setFillStyle('#000000');
console.log("width>>2>>" + width);
console.log("px>>" + px);
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
console.log("frame>>i>>" + i + ">>j>>" + j + ">>frame[]>>" + frame[j*width + i]);
if (frame[j * width + i]) {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
console.log("(px * (4 + i) + offset>>" + (px * (4 + i) + offset));
}
}
}
return new Promise(function(resolve){
console.log("drawPromise");
ctx.draw(false, function(){
console.log("ctx.draw");
resolve();
});
});
},
然后在显示的界面做image处理操作:
drawImgPromise: function(){
console.log("drawImgPromise");
return new Promise((resolve, reject) =>{
wx.canvasGetImageData({
canvasId: "mycanvas",
height: 64,
width: 64,
x: 0,
y: 0,
success:function(res){
console.log("draw>>>>>" + res.data);
console.log("draw>>>>" + res.data.length);
var result = new Uint8Array(64 * 64);
var pos = 0;
for(var i = 1, len = res.data.length; i < len; i +=4){
if(res.data[i] == 0){
result[pos++] = 1;
}else{
result[pos++] = 0;
}
}
return resolve(result);
},
fail:function(res){
console.log("fail>>" + res);
reject(res);
}
})
})
},
调用的代码为:
var QRCode = require("../../mposlib/qrcode/qrcode");
QRCode.api.draw(qrUrl, canvasId, width, height, this)
.then(() =>{
return this.drawImgPromise()
.then((res) =>{
order = this.canvasResult(res);
console.log("order>>" + utils.ab2hext(order).toUpperCase());
console.log("order>>length>>" + order.byteLength);
});
});
如此,就获得了二维码的点位图。
qrcode.js链接地址
wxml需要显示创建一个canvas的对象,因为不需要显示,做了隐藏处理
<view class="canvas-box">
<canvas style="width: 686rpx;height: 686rpx;background:#f1f1f1;" canvas-id="mycanvas" />
</view>
wxss文件
.canvas-box{
position: fixed;
top: 200%;
}