代码(由于我的项目是在electron中启动的服务、所以,我安装在devDependencies中了)
1、安装request-promise-native到本地
npm install request-promise-native --save-dev
2、配置基本的微信配置参数appid、secret、width、path
const wechatConfig = {
appid: "wx0ff86410*****d37",
secret: "b2de7240d42*****f92fff1d48848c33",
path: "/pages/index/index",
width: 430 // 这点的默认值是微信官方文档的默认值,我没变
}
3、封装get、post请求
const request = require("request-promise-native");
/**
* config:设置请求中的配置参数
* path:接口url
* data:参数
*/
const myGet = (path, data, config = {}) => {
return new Promise((resolve, reject) => {
request.get({
url: path,
method: "GET",
qs: data,
headers: config.headers,
encoding: config.encoding
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
const myPost = (path, data, config = {}) => {
return new Promise((resolve, reject) => {
request.post({
url: path,
method: "POST",
body: JSON.stringify(data),
headers: config.headers,
encoding: config.encoding
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
4、调用方法,设置响应格式
const router = require("express").Router();
const fs = require("fs");
const path = require("path");
const wechatConfig = require("../utils/utils").wechatConfig;
const { myGet, myPost } = require("../utils/utils");
router.get("/getQrCode", (req, res, next) => {
var appid = req.query.appid || wechatConfig.appid;
var secret = req.query.secret || wechatConfig.secret
var urlPath = req.query.path || wechatConfig.path
var width = req.query.width || wechatConfig.width
// 定义请求查询字串
var params = {
appid,
secret
}
myGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential", params).then(resp => {
return resp && JSON.parse(resp).access_token;
}).then(token => {
// 注意此处的encoding参数设置,即返回格式为base64
// 如果不懂,可以看第3步,对request的封装
myPost("https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + token, {
access_token: token,
path: urlPath,
width
}, { encoding: "base64" }).then(resp => {
// 将返回的base64格式转为buffer对象,通过fs写入文件夹并,写入成功后返回图片路径,否则置空,返回错误状态码
var buffer = Buffer.from(resp, "base64");
var fileName = Date.now() + ".jpeg";
var filePath = path.resolve(__dirname, "../public/assets/images/qrCode/" + fileName)
fs.writeFile(filePath, buffer, err => {
if (err) {
res.send({
code: 201,
message: "获取二维码失败",
data: null
})
} else {
res.send({
code: 200,
message: "获取二维码成功",
data: "http://" + req.headers.host + "/assets/images/qrCode/" + fileName
})
}
})
})
}).catch(err => {
res.send({
code: 500,
message: "获取二维码失败,系统繁忙,请联系管理员",
data: null
})
})
})
这一堆堆的代码,看不舒服就算啦,看我给你们通俗易懂的解释
一个一个图片通过同步方式绘制,不然他加载时间不同导致画不上,长宽高都是可变的,根据设备宽高设置的,代码就不贴了,我设置的canvas宽和高是600 x 800 等比缩放
一个一个绘制,往下看代码把,看不懂拉倒~~~~~~**[手动滑稽]**
async drawPoster() {
wx.showLoading({
title: '生成中'
})
const ctx = wx.createCanvasContext('shareCanvas')
// 设置背景透明度
ctx.globalAlpha = .9;
// 绘制背景图
ctx.clearRect(0, 0, this.data.canvasWidth / 2, this.data.canvasHeight / 2)
var imgWrapperBg = "";
await this.getImage("http://img4.imgtn.bdimg.com/it/u=4181242980,872940746&fm=26&gp=0.jpg").then(res => imgWrapperBg = res.path);
ctx.drawImage(imgWrapperBg, 0, 0, this.data.canvasWidth * 1 / 2, this.data.canvasHeight * 1 / 2);
// 设置产品图透明度
ctx.globalAlpha = 0.98;
// 绘制当前产品图
var productImg = "";
await this.getImage("https://img.alicdn.com/imgextra/i3/3327042818/O1CN01de5CEo1Wggi2oOEWU_!!3327042818.jpg").then(res => productImg = res.path)
ctx.drawImage(productImg, 0, 0, this.data.canvasWidth * 1 / 2, this.data.canvasWidth * 1 / 1.75);
// 绘制二维码
await app.getQrCode("wx0ff86410*****d37", "b2de7240d42*****f92fff1d48848c33", "/pages/introduce/introduce?id" + (this.data.productId || "") + "&s_u_id=" + (app.globalData.userId || "")).then(async img => {
var qrCode = "";
console.log(img)
await this.getImage(img).then(res => {
qrCode = res.path;
})
return qrCode
}).then(res => {
ctx.drawImage(res, this.data.canvasWidth * 5 / 12, this.data.canvasHeight * 7 / 16, this.data.canvasWidth * 1 / 12, this.data.canvasWidth * 1 / 12);
})
ctx.draw();
wx.hideLoading()
this.setData({
isCanvasModal: !this.data.isCanvasModal
})
},
getImage(src) {
return new Promise((resolve, reject) => {
wx.getImageInfo({
src: src,
success: res => {
resolve(res)
},
fail: err => {
reject(err)
}
})
})
}