最近公司的微信小程序項目因爲業務需求須要實現二維碼推廣海報,而小程序的服務端代碼是用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
,重要的事說三遍。此文章爲萬文前端原創,特此聲明!