最近公司的微信小程序项目因为业务需求须要实现二维码推广海报,而小程序的服务端代码是用node.js实现的,因为是第一次使用node.js做为服务端来实现图片的相关处理,难免走了一些坑。因此为了不你们也像我同样花费没必要要的时间爬坑,就将我再开发过程当中遇到的一些过程记录下来,供你们参考,水平有限,请相关大神多多指教。html
在开始以前,但愿你对下面两个工具的知识有必定的了解前端
request
;images
;准备海报背景图一张node
获取微信小程序二维码的方式主要有三个,具体详情请参考微信小程序官方文档;这里咱们选用getWXACodeUnlimit
接口: https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
。npm
关于微信二维码的获取有几点须要特别注意:json
- POST 参数须要转成 JSON 字符串,不支持 form 表单提交;
- 只能生成已发布的小程序的二维码。
因为该接口请求需携带ACCESS_TOKEN
参数,因此第一步得先获取它, 代码以下:小程序
const request = require('request');
/**
* [获取ACCESS_TOKEN]
* @param {[String]} appid [你的小程序appid]
* @param {[String]} secret [你的小程序secretKey]
* @return {[Object]} [Promise]
*/
function getAccessToken(appid,secret){
const url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + appid + '&secret=' + secret
return new Promise((resolve,reject)=>{
request(url, function(error, res, body) {
if (!error && res.statusCode === 200) {
resolve(JSON.parse(body));
} else {
reject(error, body)
}
})
})
}
复制代码
获取小程序二维码的注意事项:segmentfault
若是调用成功,会直接返回图片二进制内容,若是请求失败,会返回 JSON 格式的数据。微信小程序
因为二维码获取成功后返回的是图片二进制数据,可能了解node.js都会第一时间想到是用node.js的Buffer来处理二进制数据。没错,确实是用Buffer,我最初的代码以下:api
const images = require("images")
/**
* [获取二维码]
* @param {[String]} access_token [ACCESS_TOKEN]
* @return {[Object]} [Promise]
*/
function getQR(access_token) {
return new Promise((resolve,reject)=>{
const params = {
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: {
scene: 'uid=123',
width: 280
}
}
request(params, function(error, res, body) {
if (!error && res.statusCode == 200) {
//测试: 从Buffer数据中解码图像 正式运行请删除
images(new Buffer(body))
resolve(new Buffer(body))
} else {
reject(error, body)
}
})
})
}
复制代码
但运行发现,返回报错信息 Unknow format
.因而网上各类找资料,花费了大量时间找到的都是些关于buffer如何读本地文件的资料文档。后来在论坛里发现了一位好心人发来一篇文档给我。Node.js 不深也不浅得了解下编码. 阅读后发现原来是由于编码的问题。具体缘由能够看看那篇文章。其主要就是须要在request参数里设置: encoding: null
, 因此修改后的代码以下:bash
const images = require("images")
/**
* [获取二维码]
* @param {[String]} access_token [ACCESS_TOKEN]
* @return {[Object]} [Promise]
*/
function getQR(access_token) {
return new Promise((resolve,reject)=>{
const params = {
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token,
method: "POST",
json: true,
encoding: null,
headers: {
"content-type": "application/json",
},
body: {
scene: 'uid=123',
width: 280
}
}
request(params, function(error, res, body) {
if (!error && res.statusCode == 200) {
//测试: 从Buffer数据中解码图像, 正式运行请删除
images(new Buffer(body))
resolve(new Buffer(body))
} else {
reject(error, body)
}
})
})
}
复制代码
结果运行成功!
images
工具合成海报获取二维码数据后,接下来就是须要将其更咱们的海报背景图合成并保存或者上传到第三方存储服务器上。关于images库的使用请参考images官方文档, 下面直接上代码:
const images = require("images")
/**
* [二维码海报合成]
* @param {[Buffer]} buf [二维码图片Buffer数据]
*/
function composite(buf) {
images("./public/bg.png") //加载海报背景图像文件
.draw(images(buf), 60, 600) // 在(60,600)处绘制Logo
.save("./public/output.jpg", { //保存图片到本地,图片质量为50
quality : 50
});
}
复制代码
至此,全部功能已所有完成! 下面是简单的完整运行代码:
getAccessToken(appid, secret)
.then(res => {
return getQR(res.access_token)
})
.then(buf => {
composite(buf)
})
复制代码
encoding: null
, encoding: null
, encoding: null
,重要的事说三遍。此文章为万文前端原创,特此声明!