明天我会写一篇小程序中本地生成二维码的功能的文章。 小程序中本地生成二维码的功能就会趁热打铁生成。 明天给大家分享一下小程序中生成海报的功能和具体步骤。
这次分享的海报上元素相对较少,有头像、海报背景、以及用于素描的二维码(二维码的生成请参考《小程序生成本地二维码》一文)。 这一次,没有涉及任何文字。 文字提纲,但原理大致相同,本文不讨论文字提纲。
我们接下来开始
注:实现基于mpvue框架。 如果直接使用小程序自带的框架开发,需要稍作修改
过程
0-1
0-2
点击(0-1)页面“生成独家海报”>跳转至(0-2)页面制作海报
资源规划
生成海报之前需要设计、头像、海报背景图和二维码
为了生成海报时不出现闪烁或冻结页面小程序生成微信海报的网站,需要先在(0-1)页准备好这个数据
需要注意的是,生成海报时需要临时文件或本地文件。 如果是网络图片,需要通过wx.getImageInfo() api获取图片的临时路径
这里的头像使用的是网络路径,所以需要获取头像的临时临时路径。 海报背景可以直接使用本地路径。
通过weapp-qrcode生成二维码,然后返回到临时路径使用(详细生成逻辑参见文章开头的“小程序本地生成二维码”)
计划完成后,资源信息会以参数的形式传递到(0-2)页面。
let shareInfo = {
headerImg: 'tempfilepath',
bgImg: '本地路径的图片',
qrcode: 'tempfilepath'
}
wx.navigateTo({
url: '/pages/createPoster/main?shareInfo=' + JSON.stringify(shareInfo)
})
获取资源
获取(0-2)中的参数
我们公司的项目是通过mpvue搭建的,访问方式为
mounted () {
const options = this.$root.$mp.query
this.shareInfo= JSON.parse(options.shareInfo)
}
// 如果是通过微信开发工具直接开发则在onLoad函数中获取options
onLoad (options) {
const shareInfo = JSON.parse(options.shareInfo)
}
生活娱乐:春天来了,喝点雪碧可乐吧☺画布的风格是因为用两倍画布保存的图片在获取临时路强度保存图片时会比较模糊,需要对画布进行多重处理画布,通常两倍大小就足够了。 如果太大小程序生成微信海报的网站,Android 上可能会出现问题。
也可以用像素比作为放大倍数,这样更容易处理。 这里使用的像素比如下。
wx.getSystemInfo({
success (res) {
// 通过像素比计算出画布的实际大小(330x490)是展示的出来的大小
this.width = 330 * res.pixelRatio
this.height = 490 * res.pixelRatio
}
})
// 结构样式
保存图片
.canvas-poster{
background-color: #fafafa;
zoom: 50%; // 将画布缩小到50%(最好通过像素比进行缩小,像素比是2的话就是50%,如果不全是以像素比为标准,在生成图片的时候可能会出现四周黑边)
position: absolute;
left: -10000px; // 将画布隐藏在可视区域外
background: #206949;
}
生成前获取画布信息
mounted () {
var query = wx.createSelectorQuery()
query.select('#canvasPoster').boundingClientRect((res) => {
// 返回值包括画布的实际宽高
this.drawImage(res)
}).exec()
}
生成逻辑
methods: {
drawImage (canvasAttrs) {
let ctx = wx.createCanvasContext('canvasPoster', this)
let canvasW = canvasAttrs.width // 画布的真实宽度
let canvasH = canvasAttrs.height //画布的真实高度
// 头像和二维码大小都需要在规定大小的基础上放大像素比的比例后面都会 *this.systemInfo.pixelRatio
let headerW = 48 * this.systemInfo.pixelRatio
let headerX = (canvasW - headerW) / 2
let headerY = 40 * this.systemInfo.pixelRatio
let qrcodeW = 73 * this.systemInfo.pixelRatio
let qrcodeX = 216 * this.systemInfo.pixelRatio
let qrcodeY = 400 * this.systemInfo.pixelRatio
// 填充背景
ctx.drawImage(this.shareInfo.bgImg, 0, 0, canvasW, canvasH)
ctx.save()
// 控制头像为圆形
ctx.setStrokeStyle('rgba(0,0,0,.2)') //设置线条颜色,如果不设置默认是黑色,头像四周会出现黑边框
ctx.arc(headerX + headerW / 2, headerY + headerW / 2, headerW / 2, 0, 2 * Math.PI)
ctx.stroke()
//画完之后执行clip()方法,否则不会出现圆形效果
ctx.clip()
// 将头像画到画布上
ctx.drawImage(this.shareInfo.headerImg, headerX, headerY, headerW, headerW)
ctx.restore()
ctx.save()
// 绘制二维码
ctx.drawImage(this.shareInfo.qrcode, qrcodeX, qrcodeY, qrcodeW, qrcodeW)
ctx.save()
ctx.draw()
setTimeout(() => {
//下面的13以及减26推测是因为在写样式的时候写了固定的zoom: 50%而没有用像素比缩放导致的黑边,所以在生成时进行了适当的缩小生成,这个大家可以自行尝试
wx.canvasToTempFilePath({
canvasId: 'canvasPoster',
x: 13,
y: 13,
width: canvasW - 26,
height: canvasH - 26,
destWidth: canvasW - 26,
destHeight: canvasH - 26,
success: (res) => {
this.poster = res.tempFilePath
}
})
}, 200)
},
previewImg () {
if (this.poster) {
//预览图片,预览后可长按保存或者分享给朋友
wx.previewImage({
urls: [this.poster]
})
}
},
savePoster () {
if (this.poster) {
wx.saveImageToPhotosAlbum({
filePath: this.poster,
success: (result) => {
wx.showToast({
title: '海报已保存,快去分享给好友吧。',
icon: 'none'
})
}
})
}
}
}