<template> <view class="cameraBg"> <!-- position: absolute;left: 100000px; 隐藏canvas画布 --> <canvas style="width: 100%; height: 100vh;position: absolute;left: 100000px;" canvas-id="canvas" id="canvas"></canvas> <!-- 相机组件 --> <camera device-position="back" @initdone="cameraInit" flash="auto" style="width: 100%; height: 100vh"> <cover-image src="@/static/scan-frame/cameraBg.png" class="cover-img"> </cover-image> <cover-view class="noAuth" v-if="showAuth" @click="openAuth"> 您未开启摄像机权限,<cover-view class="btns">请点击开启权限</cover-view> </cover-view> <cover-view class="scanBtn" v-if="scanShow"> <cover-view class="beat" @click="scan"> <cover-image class="beatImg" src="@/static/scan-frame/album.png"></cover-image> <cover-view> 相册 </cover-view> </cover-view> <cover-view class="album" @click="takePhoto"> <cover-image class="albumImg" src="@/static/scan-frame/beat.png"></cover-image> <cover-view> 拍照 </cover-view> </cover-view> <cover-view class="inputs" @click="inputs"> <cover-image class="beatImg" src="@/static/scan-frame/inputs.png"></cover-image> <cover-view> 手动输入 </cover-view> </cover-view> </cover-view> </camera> </view> </template> <script> import { vinCode } from '@/api/car.js' export default { data() { return { scanShow: true, // 显示操作按钮 sysinfo: null, // 设备信息 imageInfo: null ,// 拍照图片信息 showAuth: false } }, onReady() { const sysinfo = uni.getSystemInfoSync() this.sysinfo = sysinfo }, onShow() { const _this = this uni.getSetting({ success(res) { console.log(res.authSetting['scope.camera']) _this.showAuth = !res.authSetting['scope.camera'] } }) }, methods: { cameraInit(e){ this.showAuth = false }, openAuth(){ uni.openSetting({ success(res) { if(res.authSetting['scope.camera']){ uni.navigateBack() } } }) }, // 手动输入 inputs(){ uni.redirectTo({ url: "/pages/vinInput/confirmVin?verifyCode=" }) }, // 相册 scan() { // 选择图片 uni.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album'], success: (res) => { this.compress(res.tempFilePaths[0],false) } }) }, delImgs(filePath){ // #ifdef MP-WEIXIN const fs = wx.getFileSystemManager(); try { const res = fs.unlinkSync(filePath) console.log(res) } catch(e) { console.error(e) } // #endif }, // 裁剪图片 cutImg(fileUrl){ const vm = this const ctx = uni.createCanvasContext('canvas') // 将拍照的图片绘制到canvas,宽高等于窗口宽高和手机窗口保持一致 ctx.drawImage(fileUrl,0,0,this.sysinfo.windowWidth,this.sysinfo.windowHeight) ctx.draw(true,()=>{ const cutW = 650 // 裁剪框宽度 const cutH = 160 // 裁剪框高度 const cutT = 400 // 裁剪框距离顶部距离 const cutL = 50 // 裁剪框距离左侧距离 // 以上裁剪框宽高及坐标是相对于实际蒙板图片的位置 const canvasW=cutW/750*this.sysinfo.windowWidth; // canvas 画布实际宽度 const canvasH=cutH/1624*this.sysinfo.windowHeight; // canvas 画布实际高度 const canvasL =cutL/750*this.sysinfo.windowWidth; // canvas 画布开始坐标x const canvasT= cutT/1624*this.sysinfo.windowHeight; // canvas 画布开始坐标y // 开始裁剪 uni.canvasToTempFilePath({ x: canvasL, y: canvasT, width: canvasW, height: canvasH, canvasId: 'canvas', success: function(res) { // 在H5平台下,tempFilePath 为 base64 vm.parseImgs(res.tempFilePath) // 删除临时文件 // vm.delImgs(fileUrl) } }) }) }, // 启动图片压缩 compress(tempFilePaths,isCut) { const vm = this vm.scanShow = false uni.showLoading({ title: '智能识别中...' }) uni.compressImage({ src: tempFilePaths, quality: 100, success: (imageRes) => { // 获取类型 uni.getImageInfo({ src: imageRes.tempFilePath, success(imageInfo) { console.log(imageInfo) vm.imageInfo = imageInfo if(isCut){ // 裁剪图片 vm.cutImg(imageRes.tempFilePath) }else{ // 相册选择的图片直接解析,这里如果需要裁剪可以跳转到裁剪图片页面在继续下一步 vm.parseImgs(imageRes.tempFilePath) } } }) } }) }, // 拿到图片转base64后在开始进行识别 parseImgs(filePath) { // 图片转base64格式 uni.getFileSystemManager().readFile({ filePath: filePath, encoding: 'base64', success: (base) => { // 拿到base64,不需要base64 就把上层的转换去掉 this.scanShow = true // 此处为后端接口 传base64图片 进行ocr识别 this.parseVinNo(base.data) }, fail: (err) => { uni.hideLoading() console.log(err) } }) }, // 点击开始拍照 takePhoto() { // 获取相机上下文对象 const ctx = uni.createCameraContext() ctx.takePhoto({ quality: 'high', success: (res) => { this.compress(res.tempImagePath,true) } }) }, // 识别vin parseVinNo(data) { const _this = this const base64Str = 'data:image/' + this.imageInfo.type + ';base64,' + data vinCode({ imageByte: data }).then(res => { console.log(res, '识别VIN') if(res.status == 200){ uni.redirectTo({ url: "/pages/vinInput/confirmVin?verifyCode=123456ads11234567&filePath="+base64Str + "&verifyCode="+res.data }) }else{ uni.showToast({ icon: 'none', title: res.message }) } uni.hideLoading() }).catch(err => { uni.hideLoading() uni.showToast({ icon: 'none', title: '系统错误或超时,请重试' }) }) }, error(e) { console.log(e.detail) } } } </script> <style lang="scss" scoped> .cameraBg { width: 100%; height: 100vh; position: fixed; .cover-img { width: 100%; height: 100vh; z-index: 1; } .noAuth{ width: 100%; z-index: 999998; position: fixed; bottom: 55vh; text-align: center; color: #999; .btns{ color: dodgerblue; } } .scanBtn { width: 100%; z-index: 99999; position: fixed; bottom: 100rpx; display: flex; flex-direction: column; justify-content: center; align-items: center; .beat { position: absolute; bottom: 0rpx; left: 100rpx; display: flex; flex-direction: column; justify-content: center; align-items: center; font-size: 24rpx; font-weight: 400; color: #ffffff; .beatImg { width: 88rpx; height: 88rpx; margin-bottom: 30rpx; } } .inputs{ position: absolute; bottom: 0rpx; right: 100rpx; display: flex; flex-direction: column; justify-content: center; align-items: center; font-size: 24rpx; font-weight: 400; color: #ffffff; .beatImg { width: 88rpx; height: 88rpx; margin-bottom: 30rpx; } } .album { display: flex; flex-direction: column; justify-content: center; align-items: center; font-size: 24rpx; font-weight: 400; color: #ffffff; .albumImg { width: 120rpx; height: 120rpx; margin-bottom: 30rpx; } } } } </style>