写在前面的话:先感谢众多素不相识但又奉献自己编程经历的大佬们,是你们奠定了我们从小白到菜鸟的进阶之路
前提准备:1)开发小程序时 我使用的是微信官方提供的基于wafer 2的后台框架,使用knex.js操作数据库,koa2实现同步异步请求
2)微信官方提供了三种生成二维码的接口 我们这儿直接使用第二个接口 即可实现无数量限制的二维码生成接口getwxacodeunlimit
3)预先浏览过官方文档, https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html
跳坑指北:不要在前端直接使用wx.request()的方式进行请求接口 因为api.weixin.qq.com无法加入到后台域名白名单中
行文思路:1)获取accessToken。为了和下面的代码统一,可以参考我的另一片博文
https://blog.csdn.net/LQ_qing/article/details/89817437
2)后端利用node.js获取到带参数二维码的Buffer
这里附上我参考的大神链接:https://www.jianshu.com/p/2c7283221748
const https = require('https')
const url = require('url')
async function getWxCode (ctx) {
const { scene, accessToken, page } = ctx.request.query
const postData = JSON.stringify({
scene, // 最多32个字符。
page
})
const wxUrl = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + accessToken
let options = url.parse(wxUrl)
options = Object.assign(options, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
})
// 获取图片二进制流
const {imgBuffer, contentType} = await new Promise((resolve, reject) => {
let req = https.request(options, (res) => {
let resData = ''
res.setEncoding('binary')
res.on('data', data => {
resData += data
})
res.on('end', () => {
// 微信api可能返回json,也可能返回图片二进制流。这里要做个判断。
const contentType = res.headers['content-type']
if (!contentType.includes('image')) {
console.log('获取小程序码图片失败,微信api返回的json为:')
console.log(JSON.parse(resData))
return resolve(null)
}
const imgBuffer = Buffer.from(resData, 'binary')
resolve({imgBuffer, contentType})
})
})
req.on('error', (e) => {
console.log('获取微信小程序图片失败')
console.error(e)
})
req.write(postData) // 写入 post 请求的请求主体。
req.end()
}).catch(() => {
return null
})
ctx.res.setHeader('Content-type', contentType)
if (imgBuffer == null) {
ctx.state.data = {
imgBuffer
}
} else {
ctx.state.data = {
imgBuffer
}
}
}
3)前端调用wx.arrayBufferToBase64把buffer转换成Base64格式
const arrayBuffer = wxResult.imgBuffer.data;
const base64 = wx.arrayBufferToBase64(arrayBuffer);
const imgurl = "data:image/PNG;base64," + base64;
4)此时,你把imgurl直接替换img中的src的话,生成的带参二维码就能在页面中显示出来。
你也可以把imgurl直接放到预览API中,用户可以长按预览图片进行保存到相册(这种方法不需要申请操作相册的权限)
wx.previewImage({
current: shareImg,
urls: [shareImg]
});
5)若你想添加其他文字,例如:”长按图片 识别图中二维码“ 等 你需要使用canvas进行绘制,然后把绘制的canvas存储到相册即可
1,先把base64转化成图片
这里附上参考的大佬链接 https://blog.csdn.net/bocongbo/article/details/84954567
通过上述链接 我们可以得到一个base64src的工具类,然后进行如下操作
const ctx = wx.createCanvasContext("shareCanvas");
base64src(imgurl, res => {
ctx.setFillStyle("white");
ctx.fillRect(0, 0, 200, 200);
ctx.drawImage(res, 70, 70, 70, 70);
ctx.setFillStyle("#63c9bb"); // 文字颜色:黑色
ctx.setFontSize(13); // 文字字号:22px
ctx.setFontSize(10);
ctx.fillText(
"长按图片保存至相册", 40, 40
);
ctx.fillText(
"并分享至朋友圈", 40, 60
);
ctx.setFontSize(8);
ctx.draw();
});
// 获取生成的图片路径 这里需要使用定时器 避免绘制时 有些数据还没有加载完
setTimeout(() => {
// 将生成的canvas图片,转为真实图片
wx.canvasToTempFilePath({
x: 0,
y: 0,
canvasId: "shareCanvas",
success: function(res) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(result) {
console.log(result);
}
},
fail: function(res) {}
});
}, 1000);