需求是小程序这边先拍摄露出手腕的照片,然后传给后端,调百度识别的api,根据返回的手腕位置,显示手表的贴图(可以拖拽旋转之类的)最后可以生成海报,保存图片到手机。
前端这边的技术点分别有
//js里面写methods: {// 拍照takePhoto() {const ctx = wx.createCameraContext()ctx.takePhoto({quality: 'high',success: (res) => {// console.log(res)this.imagePath = res.tempImagePath//保存照片临时地址}})},}
上传图片
参考文档参考文档
将红框里面的url换成后端给你的上传接口就可以啦,记得一定要去小程序开发后台配一下uploadFile合法域名,不然死活传不上去的!!!
图片拖拽功能
生成海报
这两个功能我使用了组件小程序组件-canvas拖拽组件 真的贼牛逼
但是我们的需求是,根据接口返回的位置,在手腕那里直接显示手表的图片,所以还要调整一下。
首先要注意的是,一定要用v-show 而不是v-if 不然this.$refs取不到的
然后还要注意,百度识别返回的手腕坐标,是手腕中心位置距离图片左上角的位置,单位是px。所以我们用的时候需要
uni.uploadFile({url:'写后端给你的url',//返回位置和手掌大小filePath: imagePath,name: 'file',formData: {'user': 'test'},success: (res) => {var jsarr = JSON.parse(res.data)if (jsarr.code != 200) {uni.showModal({title: '提示',content: '人体数据识别失败,请重新拍照',showCancel: false,success: (res) => {if (res.confirm) {console.log('用户点击确定');this.imagePath = ''}}});} else {console.log('xxxx',jsarr.data.wrist.x)this.watchX = jsarr.data.location.width/2this.watchY = this.watchX//贴图初始位置this.initialX = jsarr.data.wrist.x / 2 -this.watchX/2this.initialY = jsarr.data.wrist.y / 2 -this.watchX/2//控制贴图移动位置,我写死了this.minX=this.initialX-this.watchX/30this.maxX=this.initialX+this.watchX/10*9this.minY=this.initialY-this.watchY/30this.maxY=this.initialY+this.watchY/10*9this.isBody = truethis.onChangeBgImage()console.log("xy", this.initialX, this.initialY)}}})
//展示图片背景onChangeBgImage() {this.$refs.canvasRef.changeBgImage(this.imagePath)this.onAddWatch()},//显示手表onAddWatch() {this.setData({graph: {//贴图大小w: this.watchX,h: this.watchY,//贴图坐标x: this.initialX, y: this.initialY,rotate: this.rotate,//贴图位置限制minX:this.minX, maxX:this.maxX,minY:this.minY,maxY:this.maxY,type: 'image',//贴图地址url: "/static/images/watchPhoto.png"}});},
组件里面需要加上对贴图移动的限制,找到move()
move(e) {const {x,y} = e.touches[0];if (this.tempGraphArr && this.tempGraphArr.length > 0) {isMove = true; // 有选中元素,并且有移动时,设置移动标识const currentGraph = this.tempGraphArr[this.tempGraphArr.length - 1];if (currentGraph.action === 'move') {currentGraph.centerX = this.currentGraph.centerX + (x - this.currentTouch.x);currentGraph.centerY = this.currentGraph.centerY + (y - this.currentTouch.y); // 使用中心点坐标计算位移,不使用 x,y 坐标,因为会受旋转影响。//控制图片移动位置if(currentGraph.centerX<=this.graph.minX){currentGraph.centerX=this.graph.minX}if(currentGraph.centerX>this.graph.maxX){currentGraph.centerX=this.graph.maxX}if(currentGraph.centerY<=this.graph.minY){currentGraph.centerY=this.graph.minY}if(currentGraph.centerY>this.graph.maxY){currentGraph.centerY=this.graph.maxY}if (currentGraph.type !== 'text') {currentGraph.x = currentGraph.centerX - this.currentGraph.w / 2;currentGraph.y = currentGraph.centerY - this.currentGraph.h / 2;}} else if (currentGraph.action === 'transform') {console.log('图片缩放')currentGraph.transform(this.currentTouch.x, this.currentTouch.y, x, y, this.currentGraph);} // 更新4个坐标点(相对于画布的坐标系)currentGraph._rotateSquare();this.draw();}},
最后生成海报的功能,也是直接调组件的方法就可以了
/*** 导出当前画布为模板*/saveImg() {uni.showLoading({mask: true})this.$refs.canvasRef.exportFun().then(imgArr => {console.log(JSON.stringify(imgArr));this.showPoster = imgArruni.hideLoading()}).catch(e => {console.error(e);});},
大概就是这样子啦