vue3中使用摄像头拍照(监听摄像头)

本文介绍了如何在Vue.js应用中使用HTML5的getUserMediaAPI来控制摄像头,包括打开、关闭和拍照功能,以及处理兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<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>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值