uni.canvasToTempFilePath 一个可恨的API

2,830 阅读2分钟

uni-app 虐我千百遍 ,我待 uni-app 如初恋 我是被这个API给坑惨了,害我搞了整整一天
俗话说的好,周一来上班,如坐鬼门关,瞌睡的要命,清早来到公司,又是熟悉的流程,早餐、喝水、开会。
哦豁,今天这个需求有点意思
需求内容:后端返回一张图片以及对应的坐标位置点,我们根据其对应的坐标位置渲染出矩形。
一听到这个需求,不就是将图片放入canvas中在通过canvas绘制能力进行绘画,最后在将对应的canvas转换成图片。
按照步骤

  1. 获取图片
  2. 写入图片、写入矩形
  3. 导出图片 小小的三步,充满了危机

获取图片

这里我们通过 uni.getImageInfo 获取图片信息

uni.getImageInfo({
    src: url,
    type: 'png',
    success: imgInfo => {}
})

写入图片、写入矩形

console.log(imgInfo, 'info');
that.canvasWidth = imgInfo.width + 'px';
that.canvasheight = imgInfo.height + 'px';
// 设置图片在canvas上 前面两个0,0是边距, 后面是宽高
ctx.drawImage(imgInfo.path, 0, 0, imgInfo.width, imgInfo.height);
// 动态画矩形
personDataList.forEach(item => {
// 设置字体
ctx.font = '26px bold 黑体';
// 设置颜色
ctx.fillStyle = '#67C23A';
ctx.fillText('person ' + item.confidence, item.x, item.y - 8);
ctx.lineWidth = 4;
ctx.strokeStyle = '#67C23A';
ctx.strokeRect(item.x, item.y, item.width, item.height);
ctx.draw(true)

注意:这里的draw是异步函数 我们的导出图片要写到draw的回调当中
这时你会发现模拟机上可以,真机上又不行,这就蛋疼了。
这个时候我是加了个setTimeout瞒天过海。
然而一上线就GG了,有些机型加个setTimeout还不行,那怎么办勒,一路调试一路百度,终于在这篇文章中找到是因为有些机型会因为性能导出失败,那怎么办勒,多看文档你会发现有个fail钩子,我们可以在这个钩子中重写即可

导出图片

uni.canvasToTempFilePath({
	canvasId: 'handWriting',
	destWidth: imgInfo.width,
	destHeight: imgInfo.height,
	success: res => {
                console.log('over draw render ing ------', res);
		setImgList(res.tempFilePath);
                // 清空画布
		ctx.clearRect(0, 0, that.canvasWidth, that.canvasheight);
		ctx.draw();
	},
	fail: err => {
		// 如果我们导出失败,那么我们进行重新绘制
		console.log(err, 'canvasToTempFilePath 导出图片失败 重启');
                this.canvasPart(options);
	}
});

后续优化点:

  1. 图片增加加载效果、失败效果
  2. 重绘超过几次跳过

全部代码

填了坑,代码优化一下提交
搬运一篇关于手写签名的文章