拍摄截取指定区域内图片,上传图片从后端接口获取相应的图片
html
<template>
<view class="photo-view">
<camera
v-if="isShowCamera"
class="camera-box"
devic-position="width"
flash="off"
:style="{ width: windowWidth + 'px', height: windowHeight + 'px' }"
>
<cover-view class="camerabgImage">
<cover-view class="active">
<cover-image class="active-image" src="@/static/images/camera-photo.png"></cover-image>
<cover-view class="text">请将VIN码放入框中,点击拍照进行识别</cover-view>
<cover-view class="btn" @tap="takePhotoAction">
<cover-view class="button"></cover-view>
</cover-view>
<cover-view class="btn" @tap="takeAlbumAction">
<cover-view>相册</cover-view>
</cover-view>
</cover-view>
</cover-view>
</camera>
<canvas
v-if="isShowImage"
canvas-id="image-canvas"
:style="{ width: windowWidth + 'px', height: windowHeight + 'px' }"
></canvas>
</view>
</template>
js
<script>
export default {
data() {
return {
isShowCamera: false,
isShowImage: true,
image: '',
windowWidth: '',
windowHeight: '',
options: {
//type:1 //区分是哪个页面进入的:首页1、血糖历史记录页面2、添加血糖页面3、
},
}
},
onLoad(options) {
console.log(options, typeof options.type, 'options')
this.options = options
this.ctx = uni.createCameraContext()
let { windowWidth, windowHeight } = uni.getSystemInfoSync()
this.windowWidth = windowWidth
this.windowHeight = windowHeight
},
onShow: function () {
var that = this
uni.authorize({
scope: 'scope.camera',
success: function (res) {
that.isShowCamera = true
},
fail: function (res) {
console.log('' + res)
uni.showModal({
title: '请求授权您的摄像头',
content: '如需正常使用此小程序功能,请您按确定并在设置页面授权用户信息',
confirmText: '确定',
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: function (res) {
console.log('成功')
console.log(res)
if (res.authSetting['scope.camera']) {
//设置允许获取摄像头
console.log('设置允许获取摄像头')
uni.showToast({
title: '授权成功',
icon: 'success',
duration: 1000,
})
that.isShowCamera = true
} else {
//不允许
uni.showToast({
title: '授权失败',
icon: 'none',
duration: 1000,
})
uni.navigateBack({ delta: 1 })
}
},
})
} else {
//取消
uni.showToast({
title: '授权失败',
icon: 'none',
duration: 1000,
})
uni.navigateBack({ delta: 1 })
}
},
})
},
})
},
methods: {
//拍照
takePhotoAction() {
this.ctx.takePhoto({
quality: 'high', //高质量
success: (res) => {
const tempFilePath = res.tempImagePath
this.loadTempImagePath(tempFilePath)
},
fail(error) {
console.log(error)
},
})
},
// 打开相册
async takeAlbumAction() {
let tempFilePath = await this.chooseImage()
if (tempFilePath) {
this.loadTempImagePath(tempFilePath)
}
},
loadTempImagePath(options) {
var that = this
uni.getSystemInfo({
success: function (res) {
// px与rpx之间转换的公式:px = rpx / 750 * uni.getSystemInfoSync().windowWidth;
// 矩形的位置
// var image_x = 0;
// var image_y = 0;
// var image_width = that.data.windowWidth;
// var image_height = that.data.windowHeight
var image_x = (36 / 750) * uni.getSystemInfoSync().windowWidth //起始点
var image_y = (400 / 750) * uni.getSystemInfoSync().windowWidth
var image_width = (680 / 750) * uni.getSystemInfoSync().windowWidth //图片大小
var image_height = (280 / 750) * uni.getSystemInfoSync().windowWidth
console.log(image_x, image_y, image_width, image_height)
uni.getImageInfo({
src: options,
success: function (res) {
that.isShowImage = true
that.canvas = uni.createCanvasContext('image-canvas', that)
//过渡页面中,图片的路径坐标和大小
that.canvas.drawImage(options, 0, 0, that.windowWidth, that.windowHeight)
uni.showLoading({
title: '数据处理中...',
icon: 'loading',
duration: 10000,
})
// 这里有一些很神奇的操作,总结就是MD拍出来的照片规格居然不是统一的过渡页面中,对裁剪框的设定
that.canvas.setStrokeStyle('black')
that.canvas.strokeRect(image_x, image_y, image_width, image_height)
that.canvas.draw()
setTimeout(function () {
uni.canvasToTempFilePath({
//裁剪对参数
canvasId: 'image-canvas',
x: image_x, //画布x轴起点
y: image_y, //画布y轴起点
width: image_width, //画布宽度
height: image_height, //画布高度
destWidth: image_width, //输出图片宽度
destHeight: image_height, //输出图片高度
success: function (res) {
that.image = res.tempFilePath
//清除画布上在该矩形区域内的内容。
// that.canvas.clearRect(0, 0, that.data.width, that.data.height)
// that.canvas.drawImage(res.tempFilePath, image_x, image_y, image_width, image_height)
// that.canvas.draw()
// 上传图片给后端返回https链接
that.uploadTo(res.tempFilePath)
//生成base64
// uni.getFileSystemManager().readFile({
// filePath: res.tempFilePath, //图片路径
// encoding: 'base64', //编码格式
// success: result => {
// //成功的回调
// console.log('data:image/png;base64,' + result.data)
// //在此可进行网络请求
// },
// fail: function (e) {
// uni.hideLoading()
// uni.showToast({
// title: '出错啦...',
// icon: 'loading',
// })
// },
// })
},
})
}, 1000)
},
})
},
})
},
async uploadTo(tempFilePath) {
// 上传图片给后端返回https链接
let uploadRes = await this.uploadFile(tempFilePath)
console.log(uploadRes, 'uploadRes')
if (uploadRes) {
//图片解析
const data = await this.getImageData(uploadRes)
uni.hideLoading()
//解析之后跳转页面
this.goToAddRecord(data)
}
},
async chooseImage(count = 1) {
let _that = this
//从本地相册选择图片或使用相机拍照。此接口不再更新,
//建议使用 wx.chooseMedia(拍摄或从手机相册中选择图片或视频)
let res = await uni.chooseMedia({
count, //默认9
mediaType: ['image'],
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
// sourceType: ['album', 'camera'], //从相册选择,使用相机拍摄
sourceType: ['album'], //从相册选择
})
if (res[1]) {
const filePath = res[1].tempFiles[0].tempFilePath
// 返回图片地址
return filePath
} else {
return false
}
},
async uploadFile(filePath) {
let _that = this
let token = await AuthProvider.getAccessToken()
let resArr = await uni.uploadFile({
url: _that.$config.UPLOAD_FILE_URL,
name: 'file',
filePath,
header: { Authorization: token },
})
if (resArr[0]) {
console.log('识别图片报错')
_that.showError(resArr[0].errMsg)
return false
} else {
const res = resArr[1]
const resData = JSON.parse(res.data)
if (resData.code == 100) {
return resData.data.url
}
return false
}
},
getImageData(imgUrl) {
return getBloodDataApi(imgUrl + '?x-oss-process=image/resize,w_2048,h_2048,m_lfit').then((res) => {
//无论图片识别成功与否 跳转到添加页面
this.toastShow = false
this.noOnShow = false
const data = { ...res, picUrl: imgUrl }
return data
})
},
//识别图片,跳转页面
goToAddRecord(res) {
const { type } = this.options
let blood = res.code == 100 ? res.data.bloodSugarNum : '',
time = '',
path = '/packageA/pages/record/record'
if (type === '2') {
//历史记录
const addBlood = this.$utils.getStorage('addBlood')
time =
res.code == 100
? this.$date.formatDate(res.data.measurementTime, 'YYYY/MM/DD hh:mm')
: addBlood.date + ' ' + addBlood.time + ':00'
} else {
//首页//添加血糖页面
time =
res.code == 100
? this.$date.formatDate(res.data.measurementTime, 'YYYY/MM/DD hh:mm')
: this.$date.formatDate(new Date(), 'YYYY/MM/DD hh:mm')
}
// path = `/packageA/pages/record/record?bloodSugarNum=${blood}&measurementTime=${time}&code=${res.code}&picUrl=${res.picUrl}&type=${type}`
//血糖存储数据
const bloodData = {
bloodSugarNum: blood,
measurementTime: time,
code: res.code,
picUrl: res.picUrl,
type,
}
this.$utils.setStorage('bloodData', bloodData)
if (type === '1' || type === '2') {
//关闭photo当前页面,进入record
uni.redirectTo({
url: path,
}).then(() => {
if (type === '2') this.$utils.removeStorage('addBlood')
})
} else {
//记录从当前页面返回添加血糖页面
this.$utils.setStorage('goBackAdd', true)
uni.navigateBack({ delta: 1 })
}
},
},
}
</script>
<style lang="scss" scoped>
.camera-box {
width: 100vw;
height: 100vh;
}
.camera-box .camerabgImage {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.camera-box .camerabgImage .active {
position: absolute;
top: 400rpx;
left: 36rpx;
right: 36rpx;
}
.camera-box .camerabgImage .active-image {
display: block;
width: 680rpx;
height: 280rpx;
}
.camera-box .camerabgImage .text {
text-align: center;
margin-top: 56rpx;
margin-bottom: 240rpx;
font-size: 28rpx;
font-weight: 400;
color: #d9d9d9;
line-height: 40rpx;
}
.camera-box .camerabgImage .btn {
width: 110rpx;
height: 110rpx;
border-radius: 50%;
background: #fff;
border: 6rpx solid#fff;
margin: 0 auto;
}
.camera-box .camerabgImage .btn .button {
width: 102rpx;
height: 102rpx;
border-radius: 50%;
border: 4rpx solid#000;
}
.capture_image {
width: 100%;
height: auto;
position: relative;
}
</style>
参考链接: