需求:近来微信小程序有个需求,自定义相机拍照,并且要在相机中画一个框,提示用户把拍摄内容放入框中,类似于上传身份证时那个头像,国徽对其的框。(因为我们上传的是一份A4纸的病例),所以需要这样。然后后台解析上传的病例图片,返回给我病例数据,我把数据填充到表单中。
调研1: 首先想到的是调用微信的 wx.chooseImage ,由用户选择是 解析本地的图片,还是拍照,但是发现一个问题,如下:
1)无法自定义相机,导致用户没办法参考拍摄成什么样照片为合格,目前没找到办法。
调研2: 后来发现微信小程序组件提供了 camera 相机组件,经过测试,可以自定义相机。(调用相机时会有权限提示)实现方法为,写一个辅助框,定位到相机上面,就实现了。(其余身份证框,头像框实现原理可能也一样,或者用canvas 画,个人理解)
调研3: 后台说拍摄的图片大小不能超过4M,所以我需要验证一下图片的大小,但是 camera 拍照成功之后拿不到 照片的源文件,只有返回 tempImagePath (照片的临时路径,本地路径),现在计算根据临时路径来解析图片大小,
发现 官方有提供api ,wx.getFileInfo ,可以解析。但是经过测试,解析出来的图片大小,只有 0.XXXX M ,不知道为什么,可能官方压缩了。 (后来此方法注释掉了)
调研4: 刚开始我以为上传是把拍摄好的图片源文件 传给后台,后来发现传的是一个本地路径,成功之后由后台用路径解析出图片,在解析图片,然后把数据返回给我。
现在完整的流程通了,以下为代码
<!--pages/photograph/photograph.wxml-->
<!-- <text>pages/photograph/photograph.wxml</text> -->
<view class="photo">
<camera device-position="back" flash="off" binderror="cameraError" class="camera">
<view class="photo-border"></view>
</camera>
<!-- <view>{{size}}</view> -->
<!-- <image mode="widthFix" src="{{src}}"></image> -->
<van-button color="#37b9c6" block type="primary" bind:click="takePhoto">确定</van-button>
</view>
/* pages/photograph/photograph.wxss */
.photo{
/* height: 100%; */
/* width: 100%; */
position: relative;
}
.camera{
height: calc(100vh - 130rpx);
width: 100%;
position: relative;
margin-bottom: 20rpx;
}
.photo-border{
position: absolute;
left:15rpx;
top:25rpx;
width: calc(100% - 30rpx);
height: calc(100vh - 180rpx);
border: 1px solid #37b9c6;
}
// pages/photograph/photograph.js
Page({
/**
* 页面的初始数据
*/
data: {
src:'',
size:0,
},
takePhoto() {
const ctx = wx.createCameraContext()
ctx.takePhoto({
quality: 'high',
success: (res) => {
console.log(res);
// wx.getFileInfo({
// filePath:res.tempImagePath,
// success: (res)=> {
// let size=res.size/1024/1024;
// this.setData({
// size: size
// })
// console.log(res.size)
// console.log(res.digest)
// }
// })
wx.uploadFile({
url: 'url', //此处为后台服务器上传路径
filePath: res.tempImagePath,
name: 'name',
success: (res)=>{ //一下为自己的逻辑
app.globalData.photoData=res.data;
//do something
wx.navigateBack({
delta: 1 //返回上一级页面
})
},
fail:()=>{
wx.showToast({
title: '上传失败',
icon: 'none'
})
}
})
}
})
},
cameraError(e) {
console.log(e.detail)
wx.showToast({
title: '以拒绝,使用请手动开启',
icon:'none'
})
setTimeout(()=>{
wx.navigateBack({
delta: 1 //返回上一级页面
})
},3000)
}
})