一、需求说明
- 点击生成海报
- 海报有二维码,二维码在海报底部居中
- 点击保存 可将海报保存到手机相册
二、需求实现
点击【生成二维码海报】按钮时,获取图片路径,并使用 canvas 画图 出现海报后,点击【保存海报】按钮时,将画布转换为 url,并保存到本地相册
2.1 获取到图片路径
-
海报背景图 背景图片直接放进了代码的静态资源文件夹里。直接使用相对路径即可
-
二维码 二维码需要调用后端接口获得,并下载到本地获取临时路径。 调接口获取二维码路径并保存:
getPosterImage() {
wx.showLoading({
title: '正在制作海报。。。'
})
let that = this
post(api.getQRImage).then(res => {
this.setData({
qrImageUrl: res.path
})
this.getImageInfo()
})
}
由于网络图片或接口返回图片,无法直接使用,需要下载到本地获取临时路径:
getImageInfo() {
let that = this
wx.getImageInfo({
src: this.data.qrImageUrl,
success: res => {
that.drawPoster(res.path)
}
})
}
2.2 使用 canvas 画图
- 增加 canvas 标签,设置为不可见
<!-- 通过 isShowPoster 控制画布是否显示 -->
<!-- 设置画布宽高 -->
<canvas canvas-id="poster-canvas" class="{{isShowPoster ? '' : 'no-display'}}" style="width:{{windowWidth}}px;height:{{posterHeight}}px;"></canvas>
<!-- 保存海报按钮,通过 isShowPoster 控制是否显示 -->
<button class="{{isShowPoster ? '' : 'no-display'}}" bindtap="handleSavePoster">保存海报</button>
- 通过屏幕尺寸计算画布尺寸:
onLoad: function (options) {
// poster 的宽和高依据拿到的背景图宽高为准
const poster = {
"with": 375,
"height": 587
}
// 获取设备宽高信息 画布宽度等于屏幕宽度,画布高度按比例计算
const systemInfo = wx.getSystemInfoSync()
let windowWidth = systemInfo.windowWidth
let windowHeight = systemInfo.windowHeight
let posterHeight = parseInt((windowWidth / poster.with) * poster.height)
this.setData({
windowWidth: windowWidth,
posterHeight: posterHeight
})
}
- 获取 canvas context 实例:
<canvas canvas-id="canvas-container"></canvas>
drawPoster() {
let ctx = wx.createCanvasContext('canvas-container')
}
- 使用 ctx 实例的 api 绘图:
drawPoster() {
let windowWidth = this.data.windowWidth
let posterHeight = this.data.posterHeight
let ctx = wx.createCanvasContext('canvas-container')
// 绘制背景图
ctx.drawImage(this.data.backgroundUrl, 0, 0, windowWidth, posterHeight, 0, 0);
// 绘制二维码
// x坐标为 (画布宽度 - 二维码宽度) / 2
// y坐标为 (画布高度 - 二维码高度 - 底部距离)
ctx.drawImage(this.data.qrImageUrl, (windowWidth - 60) / 2, posterHeight - 70, 60, 60, 0, 0);
// 绘图
ctx.draw()
// 将画布设置为可见
this.setData({
isShowPoster: true
})
wx.hideLoading()
}
2.3 将 canvas 画布转换为 url
handleSavePoster() {
wx.showLoading({
title: '正在保存海报。。。'
})
let that = this
setTimeout(function() {
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.windowWidth,
height: that.data.posterHeight,
destWidth: that.data.windowWidth,
destHeight: that.data.posterHeight,
canvasId: 'poster-canvas',
success: function (res) {
that.setData({
posterUrl: res.tempFilePath,
})
that.saveImageToAlbum()
}
})
}, 500)
}
2.4 将该图片存储到手机相册
saveImageToAlbum() {
let that = this;
//将图片保存到相册
wx.saveImageToPhotosAlbum({
filePath: that.data.posterUrl,
success(res) {
wx.hideLoading()
wx.showModal({
title: '保存成功',
content: '图片成功保存到相册了,快去分享朋友圈吧',
showCancel: false,
confirmText: '好的',
confirmColor: '#818FFB',
success: function (res) {
// 保存成功,隐藏画布
if (res.confirm) {
that.setData({
isShowPoster: false
})
}
}
})
}
})
}

<关于我们>
我们是来自帝都的一枚前端程序猿 + 一枚前端程序媛。
这里发布的文章是我们对学习内容的总结,预计会每周至少会更新一篇。
目前我们学习计划是: 小程序实战 => vue 进阶用法 => vue 原理 => css 基础 => es6 => js 深入
另外,工作中用到的一些技术和完成的功能,我们也会及时总结更新在这里
如文章有错误或表述不清晰,欢迎各位留言反馈~~