<template>
<div class="camera_outer">
<!-- poster="背景图" -->
<video id="videoCamera" :width="videoWidth" :height="videoHeight" autoplay poster="/src/assets/images/bg_login_2.png" />
<canvas style="display: none" id="canvasCamera" :width="videoWidth" :height="videoHeight"></canvas>
<div v-if="imgSrc" class="img_bg_camera">
<img :src="imgSrc" alt="" class="tx_img" />
</div>
<el-button @click="getCompetence()">打开摄像头</el-button>
<el-button @click="stopNavigator()">关闭摄像头</el-button>
<el-button @click="setImage()">拍照</el-button>
</div>
</template>
<script setup>
import { nextTick, ref } from 'vue'
const videoWidth = ref(300)
const videoHeight = ref(300)
const imgSrc = ref('')
const thisCancas = ref(null)
const thisContext = ref(null)
const thisVideo = ref(null)
const emit = defineEmits(['refreshDataList'])
// vue中使用摄像头拍照(监听摄像头)
function getCompetence() {
thisCancas.value = document.getElementById('canvasCamera')
thisContext.value = thisCancas.value.getContext('2d')
thisVideo.value = document.getElementById('videoCamera')
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
// 使用getUserMedia,因为它会覆盖现有的属性。
// 这里,如果缺少getUserMedia属性,就添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先获取现存的getUserMedia(如果存在)
let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
// 有些浏览器不支持,会返回错误信息
// 保持接口一致
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
let constraints = { audio: false, video: { width: videoWidth.value, height: videoHeight.value, transform: 'scaleX(-1)' } }
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
// 旧的浏览器可能没有srcObject
if ('srcObject' in thisVideo.value) {
thisVideo.value.srcObject = stream
} else {
// 避免在新的浏览器中使用它,因为它正在被弃用。
thisVideo.value.src = window.URL.createObjectURL(stream)
}
thisVideo.value.onloadedmetadata = function (e) {
thisVideo.value.play()
}
})
.catch(err => {
console.log(err)
})
}
// 绘制图片(拍照功能)
function setImage() {
// 点击,canvas画图
thisContext.value.drawImage(thisVideo.value, 0, 0, videoWidth.value, videoHeight.value)
// 获取图片base64链接
let image = thisCancas.value.toDataURL('image/png')
// console.log(dataURLtoFile(image, '图片文件')) // 转换为file文件
imgSrc.value = image
emit('refreshDataList', imgSrc.value)
}
// base64转文件
function dataURLtoFile(dataurl, filename) {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
// 关闭摄像头
function stopNavigator() {
thisVideo.value.srcObject.getTracks()[0].stop()
}
nextTick(() => {
getCompetence()
})
</script>
<style scoped>
.dashboard-container {
width: 100%;
height: 100%;
color: #fff;
}
.tx_img {
max-width: 100%;
}
</style>
vue3中使用摄像头拍照(监听摄像头)
最新推荐文章于 2024-08-05 11:04:19 发布