项目中需要前端调用,所以做了如下操作
先看一下效果吧
主要是基于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.videoWidth
canvas.height = video.value.videoHeight
canvas.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.length
let u8arr =newUint8Array(n)while(n--){
u8arr[n]= bstr.charCodeAt(n)}returnnewFile([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()consttakePhoto=()=>{const canvas = document.createElement('canvas')
canvas.width = video.value.videoWidth
canvas.height = video.value.videoHeight
canvas.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 =newFormData()
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.length
let u8arr =newUint8Array(n)while(n--){
u8arr[n]= bstr.charCodeAt(n)}returnnewFile([u8arr],`${filename}.${suffix}`,{type: mime,})}constclearVideo=()=>{const stream = video.value.srcObject
const tracks = stream.getTracks()
tracks.forEach((track)=>{
track.stop()})
video.value.srcObject =null}constretake=()=>{
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>
本文转载自: https://blog.csdn.net/weixin_45289656/article/details/132567116
版权归原作者 小疯仔 所有, 如有侵权,请联系我们删除。
版权归原作者 小疯仔 所有, 如有侵权,请联系我们删除。