<template>
<!--
照片OCR取景框页面,实现两个功能: 1. 实现相机 + 取景框的拍照组合; 2. 裁剪取景框内的元素
拍照:
- APP端使用 <live-pusher> 直播流模拟相机窗口。需要在manifest.json -> APP模块配置 里勾选 LivePusher 直播流
- 小程序只用 <camera> 组件模拟相机窗口
裁剪: - APP端无法使用 canvas 的API,因为使用的是nvue文件,目前不支持官方canvase的API,可以使用官方提供的gcanvas的API。(gcanvas的drawImage不允许临时路径)
-
小程序端通过canvas提供的API可以实现
-->
<view class="live-camera" :style="{ width:
${windowWidth}px
, height:${windowHeight}px
}"> <view class="preview" :style="{ width:${windowWidth}px
, height:${windowHeight - 90 }px
}"> <!-- #ifdef APP-PLUS --> <live-pusher v-if="showLive" id="livePusher" ref="livePusher" class="livePusher" mode="FHD" beauty="0" whiteness="0" :aspect="aspect" min-bitrate="1000" audio-quality="16KHz" device-position="back" orientation="vertical" :auto-focus="true" :muted="true" :enable-camera="true" :enable-mic="false" zoom="true" @statechange="statechange" @error="error" max-bitrate="1000" style="{ width:${cameraWidth }px
, height:${windowHeight - 90}px
}"> </live-pusher>
<!-- #endif -->
<!-- #ifdef MP -->
<!-- #endif -->
</view>
<!-- 取景框辅助线 -->
<cover-view class="outline-box" <!-- style="{ width:${cameraWidth }px
, height:${windowHeight - 180 }px
}"> --> <!-- <p>覆盖的文字,很长的文字</p> -->
<cover-image class="outline-img" :src=frame style="transform:rotate(90deg)"></cover-image>
</cover-view>
<view class="menu">
<view class="photo" v-for="(image, index) in imagelist" :key="index" @click='magnify'>
<image class="imglist" :src="image" mode="aspectFill"></image>
</view>
<cover-image class="phone" :src="takingPictures" mode="" @click="snapshot()">
</cover-image>
</view>
</view>
</template>
<script>
const n = uni.requireNativePlugin("FH-PatternRecognition");
import {
judgeIosPermission,
requestAndroidPermission,
gotoAppPermissionSetting
} from "@/js_sdk/wa-permission/permission.js"
export default {
data() {
return {
// 前置或后置摄像头,值为 front,back
devicePosition: "back",
// 打开相机的轮询
openCameraInterval: null,
// 操作类型
dotype: "idcardface",
// 提示
message: "",
// 比例
aspect: "4:3",
// 相机画面宽度
cameraWidth: "",
// 相机画面高度
cameraHeight: "",
// 屏幕可用宽度
windowWidth: "",
// 屏幕可用高度
windowHeight: "",
// 相机是否准备好了
cameraState: false,
// 流视频对象
livePusher: null,
// 快照
snapshotsrc: null,
type: null,
// 安卓机需要先判断有没有授权对应权限
showLive: false,
// 取景框内的图片
imageInfo: {},
// canvas 实例对象
context: {},
rpx2px: "",
// 取景框尺寸,可以根据需要进行调整
finder: {
width: 640,
height: 980
},
//存放拍摄的照片
// imagelist: [],
//ai拍摄的照片
imagelist: [],
takingPictures: "../../static/logininteraction/phone.png", //拍照按钮
number: 0, //AI拍照的张数
frame: null,
}
},
onLoad(e) {
const equipment = this.$store.state.buildinfo.odnPortInfos.length
if (equipment == 13) {
this.frame = "../../static/logininteraction/frame11.png"
}else if(equipment == 16){
this.frame = "../../static/logininteraction/frame4one.png"
}
//
console.log(n, '调用插件')
// uni.showToast({
// title:"请横屏拍摄!",
// icon:'none'
// })
this.type = e.type;
// 可能需要根据不同类型调整取景框大小
// plus.screen.lockOrientation('landscape-primary')
this.infoData = this.$store.state.infoData;
this.fiberNumber = this.$store.state.fiberNumber;
console.log(this.infoData, '传给SDK的模板数据')
console.log(this.fiberNumber, '拿到fiberNumber传给SDK')
this.path = uni.getStorageSync('path')
console.log(this.path, '存在本地的路径')
// var url=this.path.slice(7)
// this.scrpath.push(url)
// console.log(this.scrpath,'显示本机路径')
// this.requestAndroidPermission()
this.initSDK();
// this.portRecognition(url)
},
onUnload() {
// plus.screen.lockOrientation('portrait-primary');
},
async onReady() {
console.log(this.initCamera(), '////////////')
this.initCamera();
// #ifdef APP-NVUE
if (plus.os.name === "Android") {
console.log("进入安卓")
await this.checkAndroidCamera();
} else {
this.showLive = true;
}
// #endif
// #ifdef MP
this.showLive = true;
if (await !this.checkCamera()) {
return
}
// #endif
// #ifdef APP-PLUS
if (this.showLive) {
this.$nextTick(() => {
this.livePusher = uni.createLivePusherContext("livePusher", this);
console.log("this.livePusher", this.livePusher);
})
}
// #endif
},
methods: {
// 初始化相机
initCamera() {
// 处理安卓手机异步授权问题
uni.getSystemInfo({
success: (res) => {
console.log("手机信息", res)
this.windowWidth = res.windowWidth;
this.windowHeight = res.windowHeight;
this.cameraWidth = res.windowWidth;
this.cameraHeight = res.windowWidth * 1.5;
this.rpx2px = 1 / 750 * res.windowWidth;
let imgW = parseInt(this.finder.width * this.rpx2px),
imgH = parseInt(this.finder.height * this.rpx2px) // 640和980是css里定义取景框的rpx宽度
this.imageInfo = {
width: imgW,
height: imgH
}
}
});
},
// 检查安卓相机权限
async checkAndroidCamera() {
let androidPermisson = await requestAndroidPermission("android.permission.CAMERA")
console.log("androidPermisson", androidPermisson);
if (androidPermisson === 1) {
this.showLive = true
// this.$nextTick(() => {
// this.livePusher = uni.createLivePusherContext('livePusher', this);
// console.log("this.livePusher", this.livePusher, this.$refs.LivePusher)
// })
setTimeout(() => {
//开启预览并设置摄像头
this.startPreview();
this.poenCarme()
}, 100)
} else {
uni.showModal({
content: "请打开摄像头授权功能!",
showCancel: false,
success: (res) => {
if (res.confirm) gotoAppPermissionSetting()
}
})
}
console.log("checkAndriodCamera", androidPermisson)
},
// 检查照相机权限
checkCamera() {
return new Promise(async (resolve) => {
// #ifdef APP-PLUS
if ((plus.os.name === "iOS" && !judgeIosPermission("camera"))) {
uni.showModal({
content: "请打开摄像头授权功能!",
showCancel: false,
success: (res) => {
if (res.confirm) gotoAppPermissionSetting()
}
})
resolve(false)
} else if (plus.os.name === "Android") {
let androidPermisson = await requestAndroidPermission("android.permission.CAMERA")
console.log(androidPermisson)
if (androidPermisson < 1) {
uni.showModal({
content: "请打开摄像头授权功能!",
showCancel: false
})
resolve(false)
} else {
resolve(true)
}
} else {
resolve(true)
}
// #endif
// #ifdef MP
uni.getSetting({
success: (sRes) => {
console.log(sRes)
if (sRes.authSetting["scope.camera"] === false) {
uni.showModal({
content: "请打开摄像头授权功能!",
showCancel: false
})
resolve(false)
} else {
resolve(true)
}
},
fail: (err) => {
console.log(err)
}
})
// #endif
})
},
// 轮询打开
async poenCarme() {
//#ifdef APP-PLUS
if (plus.os.name == 'Android') {
this.poenCarmeInterval = setInterval(() => {
if (!this.camerastate) this.startPreview();
}, 1000);
}
//#endif
},
// 开始预览
startPreview() {
console.log('开始预览')
console.log('this.livePusher', this.livePusher);
console.log('this.livePusher', this.livePusher.startPreview());
this.livePusher.startPreview({
success: async (a) => {
//直播推流默认是前置摄像头,预览成功后给转成后置摄像头
if (plus.os.name == "iOS") {
this.livePusher.switchCamera();
this.camerastate = true;
}
}
});
},
error(e) {
clearInterval(this.poenCarmeInterval)
console.log("error:" + JSON.stringify(e));
if (e.detail.errCode === 10001) {
uni.showModal({
content: "请打开摄像头授权功能!",
showCancel: false,
success: (res) => {
if (res.confirm) gotoAppPermissionSetting()
}
})
}
},
//停止预览
stopPreview() {
this.livePusher.stopPreview({
success: a => {
this.camerastate = false; //标记相机未启动
}
});
},
//状态
statechange(e) {
//状态改变
console.log(e);
if (e.detail.code == 1003 || e.detail.code == 1007) { //1007
this.camerastate = true;
} else if (e.detail.code == -1301) {
this.checkCamera()
this.camerastate = false;
}
},
//返回
back() {
uni.navigateBack();
},
/**
* 抓拍,因为APP端用的gcanvas,gcanvas.drawImage不允许临时图片,所以要先传一次图片
* **/
snapshot() {
const that = this;
console.log("点击事件")
// uni.navigateTo({
// url:"../facilityFlow/facilityFlow"
// })
if (!this.checkCamera()) {
return false
}
//震动
uni.vibrateShort();
// #ifdef APP-PLUS
console.log("进入上传")
console.log(this.livePusher, '抓拍创建livepush')
console.log(this.livePusher.snapshot, '抓拍事件')
this.livePusher.snapshot({
success: async e => {
that.number++
console.log("snapshot成功", e);
console.log(JSON.stringify(e));
// that.image = e.message.tempImagePath;
console.log("拍照计数", that.number);
if (that.number <= 4) {
that.imagelist.push(e.message.tempImagePath)
}
uni.saveImageToPhotosAlbum({
filePath: e.message.tempImagePath,
success: function(t) {
console.log(t, '保存本地图片')
this.path = t.path;
console.log(this.path, '路径')
uni.compressImage({
src: this.path,
quality: 100,
rotate: 270,
success: res => {
console.log(res.tempFilePath)
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function(t) {
console.log(t,
'保存本地图片')
that.path = t.path;
console.log(that.path,
'路径')
uni.setStorageSync(
'path',
that.path);
that.portRecognition(
that
.path)
}
});
}
})
}
});
var res = JSON.stringify(e.message.tempImagePath);
// console.log(res)
// uni.navigateTo({
// // url:`../../sbz/sbz?data=${res}`
// url: 'imageRecognition/imageRecognition'
// })
this.uploadImage(`file://${e.message.tempImagePath}`);
},
fail: err => {
console.log(err)
}
});
// #endif
// #ifdef MP
// const ctx = uni.createCameraContext();
// ctx.takePhoto({
// quality: 'high',
// success: (res) => {
// this.uploadImage(res.tempImagePath)
// }
// });
// #endif
},
/**
* 获取临时路径的图片宽高大小
* **/
magnify() {
let that = this
console.log("图片点击事件", 11111);
uni.previewImage({
urls: that.imagelist,
loop: true
});
console.log("图片点击事件预览照片", that.image);
},
getImageInfo(path) {
console.log(path)
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: path,
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
resolve(err)
}
})
})
},
// async uploadImage(path){
// let info = await this.getImageInfo(path) //获取临时路径的图片宽高大小
// let width = Math.round( this.rpx2px*this.finder.width/this.cameraWidth*info.width),height = Math.round(this.rpx2px*this.finder.height/(this.windowHeight-90)*info.height)
// let x = parseInt((info.width-width)/2),y = parseInt((info.height-height)/2)
// console.log("path", path);
// uni.uploadFile({
// "url": "http://10.199.101.201:4200/picRelationInfo/uploadImageForLive",
// "url": "http://10.99.20.131:9301/picRelationInfo/uploadImageForLive",
// "url": "https://www.example.com/upload",
// "filePath": path,
// "name": "file",
// "formData": {
// "objectId": "",
// "objectType": 3,
// "resource": 2,
// "pic": {}
// },
// "success": (res) => {
// console.log("图片上传成功222",res);
// },
// "fail": (err) => {
// console.log("err", err)
// },
// "complete": (complete) => {
// console.log("complete", complete);
// }
// })
// // uploadFileOSS(path).then( res => {
// // this.snapshotsrc = res.url + `?x-oss-process=image/crop,x_${x},y_${y},w_${width},h_${height}/rotate,270`
// // console.log(this.snapshotsrc)
// // this.setImage({x,y,width,height});
// // uni.navigateBack({
// // delta:2
// // })
// // }).catch( err => {
// // console.log(err)
// // errorMsg(err)
// // })
// },
//反转
flip() {
// #ifdef APP-PLUS
this.livePusher.switchCamera();
// #endif
// #ifdef MP
this.devicePosition = this.devicePosition === 'back' ? 'front' : 'back'
// #endif
},
//设置
setImage(x, y, width, height) {
let pages = getCurrentPages();
let prevPage = pages[pages.length - 3]; //上二个页面
//直接调用上二个页面的setImage()方法,把数据存到上二个页面中去
prevPage.$vm.setImage({
path: this.snapshotsrc,
type: this.type
});
},
initSDK() {
n.initSDK();
uni.setStorageSync('start', 0)
},
portRecognition(url) {
let _this = this;
const equipment = this.$store.state.buildinfo.odnPortInfos.length
console.log("equipment", equipment);
url = url.slice(7)
// console.log(this.infoData,'this.infoData,')
// console.log(this.fiberNumber,'this.fiberNumber,')
if (uni.getStorageSync('start') == 0) {
uni.setStorageSync('start', 1);
n.start(
this.infoData,
this.fiberNumber
)
}
// console.log (n.getDeviceType(),'11111111111111111')
// 识别方法
console.log(url)
n.portRecognition(
url,
(function(t) {
console.log(url)
console.log(t);
if (t.code == '48') {
_this.file_path = t.file_path
console.log(_this.file_path, '///////////////////')
_this.info = JSON.parse(t.msg);
console.log(_this.info, '=====================')
_this.info.portInfos.forEach(item => {
if (item.iState === -1) {
item.iState = 2;
}
})
_this.$store.state.portServerList = _this.info.portInfos;
// _this.$store.state.buildinfo.odnPortInfos=newbuildinfo
console.log(_this.$store.state.portServerList, '预备修改端口默认值')
//端口识别成功
if (_this.info.bPortFinish == true) {
if (equipment == 16) {
_this.frame ="../../static/logininteraction/barcode4.png"
} else if (equipment == 13) {
_this.frame ="../../static/logininteraction/barcode.png"
}
//防止sdk识别不了卡流程
uni.showToast({
title: '请识别条形码',
icon: 'none'
})
//端口条码都识别成功可以直接跳转设施流程
if (_this.info.bBarFinish == true) {
//ai采集的到的数据赋值给odnPortInfos
let b = JSON.parse(JSON.stringify(_this.$store.state
.portServerList))
let a = JSON.parse(JSON.stringify(_this.$store.state.buildinfo
.odnPortInfos))
console.log("a-----", a);
console.log("b----", b);
for (let i = 0; i < a.length; i++) {
for (let j = 0; j < b.length; j++) {
if (a[j].iState != b[j].iState) {
a[j].iState = b[j].iState
if (b[j].strBarCode) {
a[j].strBarcode = b[j].strBarCode
}
}
}
}
console.log("a-----", a);
//buildinfo整合数据
_this.$store.state.buildinfo.odnPortInfos = a
console.log("_this.$store.state.buildinfo", _this.$store.state.buildinfo);
_this.$store.state.currentStep = 2
uni.navigateTo({
url: '../facilityFlow/facilityFlow'
})
uni.showToast({
title: '识别完成',
icon: 'none'
})
} else {
if (equipment == 16) {
_this.frame ="../../static/logininteraction/barcode4.png"
} else if (equipment == 13) {
console.log(11111111);
_this.frame ="../../static/logininteraction/barcode3.png"
}
uni.showToast({
title: '请补录一次条形码',
icon: 'none'
})
}
} else {
console.log("frame1", _this.frame1);
if (equipment == 16) {
_this.frame ="../../static/logininteraction/frame4.png"
} else if (equipment == 13) {
console.log(11111111);
_this.frame ="../../static/logininteraction/frame1.png"
}
uni.showToast({
title: '请补录一次端口',
icon: 'none'
})
}
// console.log("最后的值buildinfo",_this.$store.state.buildinfo);
if (_this.number == 4) {
//ai采集的到的数据赋值给odnPortInfos
let b = JSON.parse(JSON.stringify(_this.$store.state
.portServerList))
let a = JSON.parse(JSON.stringify(_this.$store.state.buildinfo
.odnPortInfos))
console.log("a-----", a);
console.log("b----", b);
for (let i = 0; i < a.length; i++) {
for (let j = 0; j < b.length; j++) {
if (a[j].iState != b[j].iState) {
a[j].iState = b[j].iState
if (b[j].strBarCode) {
a[j].strBarcode = b[j].strBarCode
}
}
}
}
console.log("a-----", a);
//buildinfo整合数据
_this.$store.state.buildinfo.odnPortInfos = a
console.log("_this.$store.state.buildinfo", _this.$store.state.buildinfo);
_this.$store.state.currentStep = 2
uni.navigateTo({
url: '../facilityFlow/facilityFlow'
})
}
} else {
if (_this.number == 4) {
//ai采集的到的数据赋值给odnPortInfos
let b = JSON.parse(JSON.stringify(_this.$store.state
.portServerList))
let a = JSON.parse(JSON.stringify(_this.$store.state.buildinfo
.odnPortInfos))
console.log("a-----", a);
console.log("b----", b);
for (let i = 0; i < a.length; i++) {
for (let j = 0; j < b.length; j++) {
if (a[j].iState != b[j].iState) {
a[j].iState = b[j].iState
if (b[j].strBarCode) {
console.log(b[j].strBarCode, "b[j].strBarCode");
a[j].strBarcode = b[j].strBarCode
}
}
}
}
console.log("a-----", a);
//buildinfo整合数据
_this.$store.state.buildinfo.odnPortInfos = a
console.log("_this.$store.state.buildinfo", _this.$store.state.buildinfo);
}
//sdk未识别照片
uni.showToast({
title: '识别失败请补录一次条形码',
icon: 'none'
})
return
}
})
)
},
}
}
</script>
<style>
.preview {
justify-content: center;
align-items: center;
position: relative;
z-index: 1;
}
.preview .canvas {
/* visibility: hidden; */
position: absolute;
top: 0;
z-index: -1;
}
.preview .gcanvas {
z-index: -1;
position: absolute;
}
.outline-box {
position: absolute;
top: 50%;
left: 50px;
bottom: 0;
z-index: 99;
transform: translateY(-50%);
align-items: center;
justify-content: center;
display: flex;
}
.outline-img {
position: absolute;
top: 300rpx;
left: 0rpx;
z-index: 999;
/* width: 640rpx;
height: 320rpx; */
width: 800rpx;
height: 500rpx;
}
.outline-img1 {
position: absolute;
top: 400rpx;
left: 0rpx;
z-index: 999;
/* width: 640rpx;
height: 320rpx; */
width: 800rpx;
height: 400rpx;
}
.phone {
position: fixed;
bottom: 50rpx;
left: 320rpx;
width: 128rpx;
height: 128rpx;
}
.photo {
z-index: 999;
position: fixed;
bottom: 50rpx;
left: 20rpx;
width: 180rpx;
height: 120rpx;
border: 1px solid #d8d8d8;
/* transform:rotate(-90deg) */
}
.photo-number {
position: fixed;
bottom: 125rpx;
left: 185rpx;
}
</style>
0 个回复