uniapp小程序项目中使用canvas实现本地保存海报
1.问题一,使用canvas保存到本地的图片中文字模糊
解决:
<canvas :style="{width:windowW+ 'px',height:windowH + 'px' }" :width="windowW*pixelRatio"
:height="windowH*pixelRatio" canvasId="myCanv" id="myCanv"></canvas>
JS部分:
onLoad() {
this.ctx = uni.createCanvasContext('myCanv', this)
let that = this
uni.getSystemInfo({
success: function(res) {
that.windowW = res.windowWidth
that.pixelRatio = res.pixelRatio //获取设备像素比
that.rpx = that.windowW / 375 // 375为ui设计图宽度
that.windowH = 601 * that.rpx //601为自定义需要的高度
}
})
},
cans() {
// 绘制画布大小,填充颜色
this.ctx.setFillStyle("#ffffff")
this.ctx.fillRect(0, 0, this.windowW * this.pixelRatio, this.windowH * this.pixelRatio)
this.ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0) //将画布内容在水平与垂直方向放大与像素比相同的倍数
}
canvas 标签属性 width和weight与设备像素比相乘后,画布内容是缩小的,所以需要setTransform再次放大,
2. 问题2,图片在真机上不显示
我在页面上使用的图片均为上传到服务器上的图片,查找解决方法发现canvas绘制网络图片会造成真机无法显示的问题
解决:
getImge(path) {
//利用promise异步转同步
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: path,
success: function(res) {
resolve(res)
},
fail: function(res) {
reject(res)
}
})
})
},
async cans() {
// 绘制画布大小,填充颜色
this.ctx.setFillStyle("#ffffff")
this.ctx.fillRect(0, 0, this.windowW * this.pixelRatio, this.windowH * this.pixelRatio)
this.ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0)
let backImg = this.imgUrlPrefix + 'biankuang.png' //大边框
let that = this
await this.getImge(backImg).then(res => {
this.ctx.drawImage(res.path, 15 * that.rpx, 15 * that.rpx, 345 * that.rpx, 571 * that.rpx)
})
}
利用uniapp的Api, uni.getImageInfo 可以得到 图片信息,获取图片路径,但该API为异步操作,若不转为同步操作,会将图片绘制在draw()方法后,这样也不能使图片绘制在页面上,所以利用promise将其转为同步操作。
3.问题3,ios系统无法下载
解决:将保存图片的方法写在canvas的draw方法中
drawImg() {
this.ctx.draw(
uni.canvasToTempFilePath({
canvasId: 'myCanv',
success: function(res) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
complete(res) {
if (res.errMsg == "saveImageToPhotosAlbum:ok") {
uni.showToast({
content: '图片已保存到相册',
})
} else {
uni.showToast({
content: res.errMsg,
})
}
}
})
},
})
)
},
遗憾与弊端:
由于需要绘制多张图片,导致需要多次调用drawImage方法,再加上需要判断文字换行等操作,造成内容绘制时间过长。
canvas用在小程序上问题过多,且优化不易(因为有些功能处理不得不使用某种方法),canvas官方提供的优化方法之一离屏canvas在uniapp中仅支持微信小程序,不支持支付宝,所以选择直接放弃前端来开发该功能