您好,欢迎访问一九零五行业门户网

如何利用小程序的canvas来绘制二维码?

微信小程序如何生成二维码?下面本篇给大家介绍一下利用小程序的canvas能力绘制二维码的方法,希望对大家有所帮助!
在微信小程序的业务中会有一些需要展示二维码的场景。静态二维码可以直接存放在本地,使用图片方式展示,但不适合根据用户相关信息生成动态的二维码。本文将介绍下利用小程序的canvas能力绘制二维码。
1 方法一:通过wx-qr直接生成1.1 demo
微信开发者工具打开查看
含背景图
含logo
含logo+背景图
1.2 安装
# 通过 npm 安装npm i wx-qr -s# 通过 yarn 安装yarn add wx-qr
1.3 使用组件
首先在你所开发的小程序根目录 app.json 或需要使用该组件的 xxx.json 中引用组件
(注意:请不要将组件命名为 wx-xxx 开头,可能会导致微信小程序解析 tag 失败 )
{ "usingcomponents": { "qr-container": "wx-qr" }}
之后就可以在 wxml 中直接使用组件
<qr-container text="{{qrtxt}}" size="750"></qr-container>
page({ data: { qrtxt: 'https://github.com/liuxdi/wx-qr', },});
当然,还可以支持很多种配置,详见github 或者 码云文档。
2. 方式二:基于qrcode.js结合canvas绘制2.0 二维码的组成部分
定位图案position detection pattern是定位图案,用于标记二维码的矩形大小。这三个定位图案有白边叫separators for postion detection patterns。之所以三个而不是四个意思就是三个就可以标识一个矩形了。
timing patterns也是用于定位的。原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。
alignment patterns 只有version 2以上(包括version2)的二维码需要这个东东,同样是为了定位用的。
功能性数据format information 存在于所有的尺寸中,用于存放一些格式化数据的。
version information 在 >= version 7以上,需要预留两块3 x 6的区域存放一些版本信息。
数据码和纠错码除了上述的那些地方,剩下的地方存放 data code 数据码 和 error correction code 纠错码。2.1 引入二维码数据生成库
复制qrcode.js至你的小程序相应目录。
2.2 小程序中建立canvas标签,并给canvas设置长宽
<canvas id="qr" type="2d" style="height: 750rpx;width: 750rpx;"></canvas>
2.3获取canvas实例及上下文
const query = this.createselectorquery();let dpr = wx.getsysteminfosync().pixelratio;query.select('#qr').fields({ node: true, size: true, id: true }) .exec((res) => { let { node: canvas, height, width } = res[0]; let ctx = canvas.getcontext('2d'); canvas.width = width * dpr canvas.height = height * dpr ctx.scale(dpr, dpr); })
2.4 定义一些变量及绘制二维码的数据码区
其中qrcodemodel是从qrcode.js中导入的
// 二维码的颜色const colordark = '#000';// 获取二维码的大小,因css设置的为750rpx,将其转为pxconst rawviewportsize = getpxfromrpx(750);// 二维码容错率{ l: 1, m: 0, q: 3, h: 2 }const correctlevel = 0;// 创建二维码实例对象,并添加数据进行生成const qrcode = new qrcodemodel(-1, correctlevel);qrcode.adddata(url);qrcode.make();// 每个方向的二维码数量const ncount = qrcode.modulecount;// 计算每个二维码方块的大小const nsize = getroundnum(rawviewportsize / ncount, 3)// 每块二维码点的大小比例const datascale = 1;// 计算出datascale不为1时,每个点的偏移值const dataxyoffset = (1 - datascale) * 0.5;// 循环行列绘制数据码区for (let row = 0; row < ncount; row++) { for (let col = 0; col < ncount; col++) { // row 和 col 处的模块是否是黑色区 const bisdark = qrcode.isdark(row, col); // 是否是二维码的图案定位标识区 position detection pattern(如本模块,是三个顶点位置处的大方块) const isblkposctr = (col < 8 && (row < 8 || row >= ncount - 8)) || (col >= ncount - 8 && row < 8); // 是否是timing patterns,也是用于协助定位扫描的 const istiming = (row == 6 && col >= 8 && col <= ncount - 8) || (col == 6 && row >= 8 && row <= ncount - 8); // 如果是这些区域 则不进行绘制 let isprotected = isblkposctr || istiming; // 计算每个点的绘制位置(left,top) const nleft = col * nsize + (isprotected ? 0 : dataxyoffset * nsize); const ntop = row * nsize + (isprotected ? 0 : dataxyoffset * nsize); // 描边色、线宽、填充色配置 ctx.strokestyle = colordark; ctx.linewidth = 0.5; ctx.fillstyle = bisdark ? colordark : "rgba(255, 255, 255, 0.6)"; // 如果不是标识区,则进行绘制 if (!isprotected) { ctx.fillrect( nleft, ntop, (isprotected ? (isblkposctr ? 1 : 1) : datascale) * nsize, (isprotected ? (isblkposctr ? 1 : 1) : datascale) * nsize ); } }}
此时已经绘制出二维码的数据码区:
2.5 绘制图形识别区
// 绘制position detection patternctx.fillstyle = colordark;ctx.fillrect(0, 0, 7 * nsize, nsize);ctx.fillrect((ncount - 7) * nsize, 0, 7 * nsize, nsize);ctx.fillrect(0, 6 * nsize, 7 * nsize, nsize);ctx.fillrect((ncount - 7) * nsize, 6 * nsize, 7 * nsize, nsize);ctx.fillrect(0, (ncount - 7) * nsize, 7 * nsize, nsize);ctx.fillrect(0, (ncount - 7 + 6) * nsize, 7 * nsize, nsize);ctx.fillrect(0, 0, nsize, 7 * nsize);ctx.fillrect(6 * nsize, 0, nsize, 7 * nsize);ctx.fillrect((ncount - 7) * nsize, 0, nsize, 7 * nsize);ctx.fillrect((ncount - 7 + 6) * nsize, 0, nsize, 7 * nsize);ctx.fillrect(0, (ncount - 7) * nsize, nsize, 7 * nsize);ctx.fillrect(6 * nsize, (ncount - 7) * nsize, nsize, 7 * nsize);ctx.fillrect(2 * nsize, 2 * nsize, 3 * nsize, 3 * nsize);ctx.fillrect((ncount - 7 + 2) * nsize, 2 * nsize, 3 * nsize, 3 * nsize);ctx.fillrect(2 * nsize, (ncount - 7 + 2) * nsize, 3 * nsize, 3 * nsize);// 绘制position detection pattern 完毕// 绘制timing patternsconst timingscale = 1;const timingxyoffset = (1 - timingscale) * 0.5;for (let i = 0; i < ncount - 8; i += 2) { _drawdot(ctx, 8 + i, 6, nsize, timingxyoffset, timingscale); _drawdot(ctx, 6, 8 + i, nsize, timingxyoffset, timingscale);}// 绘制timing patterns 完毕
这时候,一个朴素的二维码就绘制成功啦~
具体代码详见微信小程序代码片段
https://developers.weixin.qq.com/s/whjj73mx7bwv
该代码只是提供了一个简单二维码的生成逻辑。若需要更复杂的二维码展示功能,还是建议使用wx-qr或参考里面的具体代码。欢迎各位提issue和star~~
【相关学习推荐:小程序开发教程】
以上就是如何利用小程序的canvas来绘制二维码?的详细内容。
其它类似信息

推荐信息