vue打开摄像头=>拍照(原理和代码)=>base64

本文详细介绍了如何在Vue项目中使用getUserMedia进行摄像,包括最小代码实现、onMounted钩子的作用,以及如何利用canvas实现拍照并保存为base64格式。还讨论了将canvas从模板中分离以提高效率的方法。
摘要由CSDN通过智能技术生成

1. 先来随便创建一个vue项目

......

2. 拍摄代码最小实现

接着App.vue:

<template>
  <div style="width:600px;height:400px">
    <video id="video1" src="" style="width:100%;height:100%;background:green" autoplay></video>
  </div>
</template>
<script setup>
import {onMounted} from 'vue'
onMounted(() => {
  var video=document.getElementById('video1')
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {video.srcObject = stream;})
    .catch(err => {console.log(err);});
})
</script>

这些代码应该就是进行摄像的最少代码结构了,你直接运行项目打开网页就会发现已经打开相机了:

这些代码都是简单的不要不要的,就不解释了。

但是需要非常注意一个地方就是onMounted这个生命周期钩子函数,为什么要添加这个嘞。

实际上,如果没有onMounted这个生命周期钩子函数,而是直接运行钩子函数里面的代码,你大概率会得到一个报错的结果。

因为里面的代码不能一开始就运行因为dom元素还没有创建完成。这个onMounted函数只是为了保证dom元素都创建出来了,然后才去执行的函数。根据这个思路,你也可以不使用onMounted(前提是这个函数里面的代码不能还没创建完成dom元素就运行)。像下面,我也可以通过按钮来触发:

<template>
  <div style="width:600px;height:400px" @click="f1">
    <video id="video1" src="" style="width:100%;height:100%;background:green" autoplay></video>
  </div>
</template>
<script setup>
function f1(){
  var video=document.getElementById('video1')
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {video.srcObject = stream;})
    .catch(err => {console.log(err);});
}
</script>

另外这里还有个需要注意的地方,那就是video上面的autoplay属性,也可以省略掉,在video.srcObject=stream赋值之后,video.play即可,也就是:

<template>
  <div style="width:600px;height:400px" @click="f1">
    <video id="video1" src="" style="width:100%;height:100%;background:green"></video>
  </div>
</template>
<script setup>
function f1(){
  var video=document.getElementById('video1')
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {video.srcObject = stream;video.play()})
    .catch(err => {console.log(err);});
}
</script>

3. 然后我们开始实现拍照

原理就是,通过canvas来获取video当时的图像,什么时候拍照,就什么时候将vanvas中的图像转成base64格式的数据,再将该base64数据直接赋值给img的src即可。

为此,我们需要去创建一个canvas(因为canvas此时不需要显示出来,同时也不需要占用位置,因此可以设置display属性为none)和一个img(用来放拍摄的结果)。当我们点击按钮(这里直接在img上面的div添加一个@click属性即可,按钮就不添加了)。

<template>
  <div style="width:600px;height:400px" @click="f1">
    <video id="video1" src="" style="width:100%;height:100%;background:green"></video>
  </div>
  <div style="width:600px;height:400px;display:none">
    <canvas id="canvas1" src="" style="width:600px;height:400px;;display:none"></canvas>
  </div>
  <div @click="f2" style="width:600px;height:400px;background:green">
    <img id="img1" src=""  alt="" style="width:100%;height:100%">
  </div>
</template>
<script setup>
function f1(){
  var video=document.getElementById('video1')
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {video.srcObject = stream;video.play()})
    .catch(err => {console.log(err);});
}
function f2(){
  var video=document.getElementById('video1')
  var canvas=document.getElementById('canvas1')
  var img=document.getElementById('img1')
  console.log("ddd");
  canvas.getContext('2d').drawImage(video, 0,0,canvas.width,canvas.height);//内容关联
  img.src=canvas.toDataURL('image/png')
}
</script>

这些代码咋一看没啥大问题,但是我们理一下思路,可以发现这个过程中canvas只是起一个中间转换的效果,为什么要给它放到template中嘞?这不合理,不应该把他添加在里面。为此,我们可以在js代码中创建临时的canvas而不是写在template中,用完之后删除canvas即可。代码如下:

<template>
  <div style="width:600px;height:400px" @click="f1">
    <video id="video1" src="" style="width:100%;height:100%;background:green"></video>
  </div>
  <div @click="f2" style="width:600px;height:400px;background:green">
    <img id="img1" src=""  alt="" style="width:100%;height:100%">
  </div>
</template>
<script setup>
function f1(){
  var video=document.getElementById('video1')
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {video.srcObject = stream;video.play()})
    .catch(err => {console.log(err);});
}
function f2(){
  var video=document.getElementById('video1')
  var canvas=document.createElement("canvas")//创建canvas
  canvas.style="width:600px;height:400px;;display:none"
  var img=document.getElementById('img1')
  console.log("ddd");
  canvas.getContext('2d').drawImage(video, 0,0,canvas.width,canvas.height);//内容关联
  img.src=canvas.toDataURL('image/png')
  canvas.remove()//销毁canvas
}
</script>
4. 扩展

从f2中的canvas.toDataURL('image/png'),是一个base64格式的字符串数据,可以直接传给后端来对截图进行处理

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue中调用摄像头拍照功能可以使用`getUserMedia` API和`<video>`元素来实现。下面是一个简单的示例: 首先,你需要在Vue组件中创建一个`<video>`元素来显示摄像头捕获的视频流: ```vue <template> <div> <video ref="videoElement"></video> <button @click="capturePhoto">拍照</button> </div> </template> <script> export default { mounted() { this.initCamera(); }, methods: { async initCamera() { try { const stream = await navigator.mediaDevices.getUserMedia({ video: true }); this.$refs.videoElement.srcObject = stream; } catch (error) { console.error("无法访问摄像头:", error); } }, capturePhoto() { const videoElement = this.$refs.videoElement; const canvas = document.createElement("canvas"); canvas.width = videoElement.videoWidth; canvas.height = videoElement.videoHeight; canvas.getContext("2d").drawImage(videoElement, 0, 0); // 将图像数据转为Base64编码的字符串 const photoDataUrl = canvas.toDataURL("image/png"); // 在这里你可以对照片数据进行处理或者发送到服务器 console.log(photoDataUrl); }, }, }; </script> ``` 上述代码中,`getUserMedia` API用于获取摄像头的视频流,并通过`srcObject`将视频流赋值给`<video>`元素的属性,从而实现在网页中显示摄像头捕获的图像。 当用户点击"拍照"按钮时,`capturePhoto`方法会将视频帧绘制到一个`<canvas>`元素上,并将图像数据转为Base64编码的字符串,你可以在此处对照片数据进行处理或者发送到服务器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值