This commit is contained in:
lichuanyang 2025-02-26 15:23:17 +08:00
parent 474dbd795e
commit 6b829cd66f
4 changed files with 1487 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,9 @@
import request from '@/config/axios'
/*
*
* PhysicalEnrollApi
*/
export const PhysicalEnrollApi = {
}

View File

@ -0,0 +1,384 @@
<template>
<el-dialog
v-model="show"
title="人脸采集"
width="640px"
:close-on-click-modal="false"
:close-on-press-escape="false"
@open="
() => {
updateDialog()
}
"
@close="
() => {
updateDialog()
}
"
>
<el-divider class="!-mt-10px !mb-16px" />
<div style="display: flex; justify-content: center">
<video id="video" width="480px" height="360px" v-if="!option.img"></video>
</div>
<div style="height: 360px; width: 480px; text-align: center" v-if="option.img">
<VueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:centerBox="option.centerBox"
:infoTrue="option.infoTrue"
:fixedBox="option.fixedBox"
/>
</div>
<canvas style="display: none" id="canvasCamera" width="500" height="500"></canvas>
<template #footer>
<el-divider class="!mb-8px !mt-2px" />
<div>
<input
type="file"
style="width: 40%"
:value="fileValue"
id="upImageFile"
@change="chooseImage"
/>
<el-button type="info" @click="changeDevice">切换</el-button>
<el-button type="warning" @click="rephotograph">重拍</el-button>
<el-button type="primary" @click="setImage">拍照</el-button>
<el-button type="success" @click="confirmSubmit" :disabled="!option.img">确认</el-button>
<el-button
@click="
() => {
closeModal()
}
"
>
取消
</el-button>
</div>
</template>
</el-dialog>
</template>
<script type="text/babel">
import { VueCropper } from 'vue-cropper'
export default {
name: 'PhotographView',
components: { VueCropper },
expose: ['openDialog'],
props: {},
emits: ['handleSearch'],
data() {
return {
messageBox: useMessage(),
videoArr: [],
videoIndex: 0,
uploadAvatarShow: false, //
fileValue: '',
iconBase64: '',
show: false,
imgUrl: '',
cropperDialogVisible: false,
// option
option: {
img: '', //
info: true, //
outputSize: 0.8, //
outputType: 'png', //
canScale: false, //
autoCrop: true, //
autoCropWidth: 150, //
autoCropHeight: 200, //
canMove: true,
fixedBox: false, //
fixed: false, //
// fixedNumber: [1, 1], //
full: true, //
canMoveBox: false, //
original: false, //
centerBox: false, //
infoTrue: false, // true false
stream: null
}
}
},
created() {
this.getVideoArr()
},
methods: {
openDialog() {
this.show = true
},
updateDialog() {
if (this.show) {
this.videoIndex = 0
this.option = {
img: '', //
info: true, //
outputSize: 0.8, //
outputType: 'png', //
canScale: false, //
autoCrop: true, //
autoCropWidth: 150, //
autoCropHeight: 200, //
canMove: true,
fixedBox: false, //
fixed: false, //
// fixedNumber: [1, 1], //
full: true, //
canMoveBox: false, //
original: false, //
centerBox: false, //
infoTrue: false // true false
}
this.getCompetence()
this.imgUrl = ''
} else {
this.stopNavigator()
this.closeModal()
}
},
//
closeModal() {
this.show = false
},
//
getVideoArr() {
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
this.videoArr = []
devices.forEach((device) => {
//audioautput videoinput
if (device.kind == 'videoinput') {
this.videoArr.push({
label: device.label,
id: device.deviceId
})
}
})
})
.catch(function (err) {
this.messageBox.error(err.name + ': ' + err.message)
})
},
//
changeDevice() {
if (this.videoArr && this.videoArr.length > 0) {
let length = this.videoArr.length - 1
if (length == this.videoIndex && this.videoIndex != 0) {
this.videoIndex = this.videoIndex - 1
this.setDevice()
} else if (length > this.videoIndex && this.videoIndex == 0) {
this.videoIndex = this.videoIndex + 1
this.setDevice()
} else {
this.setDevice()
}
}
},
setDevice() {
if (this.videoArr[this.videoIndex] && this.videoArr[this.videoIndex].id) {
this.setCurrentDevice(this.videoArr[this.videoIndex].id)
}
},
setCurrentDevice(val) {
const videoConstraints = {}
if (val === '') {
videoConstraints.facingMode = 'environment'
} else {
videoConstraints.deviceId = { exact: val }
}
var constraints = {
video: videoConstraints
}
this.getUserMedia(constraints)
},
getUserMedia(constraints, success, error) {
let _this = this
if (navigator.mediaDevices.getUserMedia) {
//API
navigator.mediaDevices
.getUserMedia(constraints)
.then((success) => {
if (!_this.thisVideo) {
_this.thisVideo = document.getElementById('video')
}
// srcObject
if (_this.thisVideo && (!_this.thisVideo.srcObject || 'srcObject' in _this.thisVideo)) {
_this.thisVideo.srcObject = success
} else {
// 使
_this.thisVideo.src = window.URL.createObjectURL(success)
}
_this.stream = success
_this.thisVideo.onloadedmetadata = function (e) {
_this.thisVideo.play()
}
})
.catch((err) => {
console.log(err)
_this.changeDevice() //
})
} else if (navigator.webkitGetUserMedia) {
//webkit
navigator.webkitGetUserMedia(constraints, success, error)
} else if (navigator.mozGetUserMedia) {
//firfox
navigator.mozGetUserMedia(constraints, success, error)
} else if (navigator.getUserMedia) {
//API
navigator.getUserMedia(constraints, success, error)
}
},
//
confirmSubmit() {
this.$refs.cropper.getCropBlob((data) => {
if (data) {
// imageList
var reader = new FileReader()
reader.readAsDataURL(data)
reader.onload = () => {
this.imgUrl = reader.result
if (!this.imgUrl) {
this.messageBox.error('请点击拍照!')
return
}
this.$emit('handleSearch', this.imgUrl)
this.closeModal()
}
} else {
this.messageBox.error('图片错误!')
}
})
},
getCompetence() {
var _this = this
this.thisVideo = document.getElementById('video')
// mediaDevices
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
// mediaDevices
// 使getUserMedia
// getUserMedia
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// getUserMedia()
var getUserMedia =
navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
//
//
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
// 使Promisenavigator.getUserMedia
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
var constraints = {
audio: false,
video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' }
}
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
if (!_this.thisVideo) {
_this.thisVideo = document.getElementById('video')
}
// srcObject
if (_this.thisVideo && (!_this.thisVideo.srcObject || 'srcObject' in _this.thisVideo)) {
_this.thisVideo.srcObject = stream
} else {
// 使
_this.thisVideo.src = window.URL.createObjectURL(stream)
}
_this.stream = stream
_this.thisVideo.onloadedmetadata = function (e) {
_this.thisVideo.play()
}
})
.catch((err) => {
console.log(err)
_this.changeDevice() //
})
},
//
setImage() {
if (!this.option.img) {
this.thisCancas = document.getElementById('canvasCamera')
this.thisContext = this.thisCancas.getContext('2d')
//
this.thisContext.clearRect(0, 0, this.thisCancas.width, this.thisCancas.height)
this.thisVideo = document.getElementById('video')
var _this = this
// canvas
_this.thisContext.drawImage(_this.thisVideo, 0, 0, 500, 500)
// base64
var image = this.thisCancas.toDataURL('image/png')
this.option.img = image
}
},
//
stopNavigator() {
if (this.stream && this.stream.getTracks() && this.stream.getTracks().length > 0) {
this.stream.getTracks().forEach((track) => {
if (track) {
track.stop()
}
})
}
this.stream = null
//this.$router.go(0); //
},
//
rephotograph() {
this.option.img = ''
//
this.stopNavigator()
//
this.getCompetence()
},
//
chooseImage() {
let files = document.getElementById('upImageFile').files[0]
this.ImageToBase64(files)
},
//Base64
ImageToBase64(files) {
if (files) {
let _this = this
var reader = new FileReader()
reader.readAsDataURL(files)
reader.onload = () => {
_this.iconBase64 = reader.result
// base64
_this.option.img = _this.iconBase64
}
} else {
this.messageBox.error('图片错误!')
}
}
}
}
</script>
<style lang="scss" scoped>
.photograph {
}
</style>

File diff suppressed because it is too large Load Diff