当前位置: 首页 > news >正文

前端调用电脑摄像头

项目中需要前端调用,所以做了如下操作
先看一下效果吧
主要是基于vue3,通过canvas把画面转成base64的形式,然后是把base64转成
file文件,最后调用了一下上传接口

在这里插入图片描述
以下是代码

进入页面先调用一下摄像头

navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {video.value.srcObject = stream}).catch((error) => {console.error(error)})state.photoUrl = ''state.photo = true

拍照


const canvas = document.createElement('canvas')canvas.width = video.value.videoWidthcanvas.height = video.value.videoHeightcanvas.getContext('2d').drawImage(video.value, 0, 0, canvas.width, canvas.height)state.photoUrl = canvas.toDataURL('image/png')

转base64

  let arr = dataurl.split(',')let mime = arr[0].match(/:(.*?);/)[1]let suffix = mime.split('/')[1]let bstr = atob(arr[1])let n = bstr.lengthlet u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}return new File([u8arr], `${filename}.${suffix}`, {type: mime,})

完整代码

<template><div><div><div>摄像头实时画面</div><div class="hm"><video ref="video" v-if="state.photo" autoplay></video><img :src="state.photoUrl" v-else></div></div><div class="maT10"><el-button @click="takePhoto">拍照</el-button><el-button @click="retake">重拍</el-button></div></div>
</template><script setup lang="ts" name="photo">
import axios from 'axios'
const state = reactive({photo: true,photoUrl: '',
})
const video = ref()const takePhoto = () => {const canvas = document.createElement('canvas')canvas.width = video.value.videoWidthcanvas.height = video.value.videoHeightcanvas.getContext('2d').drawImage(video.value, 0, 0, canvas.width, canvas.height)state.photoUrl = canvas.toDataURL('image/png')clearVideo()state.photo = falselet file = base64ImgtoFile(state.photoUrl)let param = new FormData()param.append('file', file, file.name)param.append('fileReName', 'true')let config = {headers: {'Content-Type': 'multipart/form-data',Authorization: 'token',  //此处是token},}let url = import.meta.env.VITE_API_URL + '/api/admin/file/upload-file'axios.post(url, param, config).then((response) => {})
}
const base64ImgtoFile = (dataurl, filename = 'file') => {let arr = dataurl.split(',')let mime = arr[0].match(/:(.*?);/)[1]let suffix = mime.split('/')[1]let bstr = atob(arr[1])let n = bstr.lengthlet u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}return new File([u8arr], `${filename}.${suffix}`, {type: mime,})
}
const clearVideo = () => {const stream = video.value.srcObjectconst tracks = stream.getTracks()tracks.forEach((track) => {track.stop()})video.value.srcObject = null
}const retake = () => {navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {video.value.srcObject = stream}).catch((error) => {console.error(error)})state.photoUrl = ''state.photo = true
}onMounted(() => {retake()
})
//在离开当前页面的时候把摄像头关了,不然页面一直会显示摄像头的图标
onBeforeUnmount(() => {video.value.srcObject = null
})
</script><style scoped lang="scss">
.hm {width: 400px;height: 300px;video,img {width: 100%;}
}
</style>
http://www.lryc.cn/news/146884.html

相关文章:

  • 网络编程day1——进程间通信-socket套接字
  • Android-关于页面卡顿的排查工具与监测方案
  • VueX 与Pinia 一篇搞懂
  • 指针与空间按钮的交互
  • java八股文面试[数据库]——慢查询优化
  • 《Flink学习笔记》——第十章 容错机制
  • 【LeetCode-中等题】230. 二叉搜索树中第K小的元素
  • DQL语句的用法(MySQL)
  • 【Navicat Premium 16】使用Navicat将excel的数据进行单表的导入,详细操作
  • 学习笔记230810--vue项目中get请求的两种传参方式
  • 分享一种针对uni-app相对通用的抓包方案
  • 【2023百度之星备赛】码蹄集 BD202301 公园(BFS求最短路)
  • 2022年下半年系统架构设计师真题(下午带答案)
  • 26、ADS瞬时波形仿真-TRANSIENT仿真(以共射放大器为例)
  • 【微服务部署】02-配置管理
  • NTP时钟同步服务器
  • webassembly003 ggml GGML Tensor Library part-2 官方使用说明
  • ES主集群的优化参考点
  • 全国范围内-二手房小区数据-2023-8月更新
  • 第4章 循环变换
  • spring cloud使用git作为配置中心,git开启了双因子认证,如何写本地配置文件
  • JVM内存管理、内存分区:堆、方法区、虚拟机栈、本地方法栈、程序计数器
  • L1-047 装睡(Python实现) 测试点全过
  • Mysql优化原理分析
  • 软考高级系统架构设计师系列案例考点专题一:软件架构设计
  • css实现垂直上下布局的两种常用方法
  • 【Jetpack】Navigation 导航组件 ⑤ ( NavigationUI 类使用 )
  • 基于NAudio实现简单的音乐播放器
  • C++之“00000001“和“\x00\x00\x00\x01“用法区别(一百八十六)
  • Java“魂牵”京东店铺所有商品数据接口,京东店铺所有商品API接口,京东API接口申请指南