uni-app 虐我千百遍 ,我待 uni-app 如初恋 我是被这个API给坑惨了,害我搞了整整一天
俗话说的好,周一来上班,如坐鬼门关,瞌睡的要命,清早来到公司,又是熟悉的流程,早餐、喝水、开会。
哦豁,今天这个需求有点意思
需求内容:后端返回一张图片以及对应的坐标位置点,我们根据其对应的坐标位置渲染出矩形。
一听到这个需求,不就是将图片放入canvas中在通过canvas绘制能力进行绘画,最后在将对应的canvas转换成图片。
按照步骤
- 获取图片
- 写入图片、写入矩形
- 导出图片 小小的三步,充满了危机
获取图片
这里我们通过 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);
}
});
后续优化点:
- 图片增加加载效果、失败效果
- 重绘超过几次跳过