广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue调用PC摄像头实现拍照功能
  • 682
分享到

Vue调用PC摄像头实现拍照功能

2024-04-02 19:04:59 682人浏览 薄情痞子
摘要

本文实例为大家分享了Vue调用PC摄像头实现拍照功能的具体代码,供大家参考,具体内容如下 项目需求:可以本地上传头像,也可以选择拍摄头像上传。 组件: 1、Camera组件:实现 打

本文实例为大家分享了Vue调用PC摄像头实现拍照功能的具体代码,供大家参考,具体内容如下

项目需求:可以本地上传头像,也可以选择拍摄头像上传。

组件:

1、Camera组件:实现 打开、关闭摄像头、绘制、显示图片、用于上传
2、CameraDialog组件:使用ElementUI dialog组件 展示摄像头UI效果
3、外部调用CameraDialog组件,实现拍摄头像上传功能
4、本地上传可使用原生input、也可使用ElementUI upload组件

操作逻辑:

1、新增时将头像图片转为base64调用接口提交,返回url地址用于前端展示
2、替换时,先执行删除操作,在依新增操作执行。
3、本地上传原理跟拍摄上传一致

具体实现方法:

Camera组件


<template>
  <div class="camera-box">
    <video id="video" :width="videoWidth" :height="videoHeight" v-show="!imgSrc"></video>
    <canvas id="canvas" :width="videoWidth" :height="videoHeight" v-show="imgSrc"></canvas>
    <p class="camera-p">{{!imgSrc?'提示:请将头像居中按"拍照"键确认':''}}</p>
    <el-button type="primary" @click="setImage" v-if="!imgSrc" class="camera-btn">拍照</el-button>
    <el-button type="primary" v-if="imgSrc" @click="setFileUpload" class="camera-btn">上传</el-button>
  </div>
</template>

<script>
  import {setFileUpload, deleteFileUpload, addUserCard } from "@/api/houseApi";

  export default {
    name: 'Camera',
    props: {
      //【必选】CameraDialog弹窗显示状态
      show: {type: Boolean},
      //【可选】配合原生input本地上传,用于替换时执行删除
      deleteData: {type: Object}
    },
    data() {
      return {
        videoWidth: '401',
        videoHeight: '340',
        thisCancas: null,
        thisContext: null,
        thisVideo: null,
        imgSrc: ``,
      }
    },
    mounted() {
      if (this.show) this.getCompetence()
    },
    methods: {
      
      getCompetence() {
        var _this = this
        this.thisCancas = document.getElementById('canvas')
        this.thisContext = this.thisCancas.getContext('2d')
        this.thisVideo = document.getElementById('video')
        // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
        if (navigator.mediaDevices === undefined) {
          navigator.mediaDevices = {}
        }
        // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
        // 使用getUserMedia,因为它会覆盖现有的属性。
        // 这里,如果缺少getUserMedia属性,就添加它。
        if (navigator.mediaDevices.getUserMedia === undefined) {
          navigator.mediaDevices.getUserMedia = function (constraints) {
            // 首先获取现存的getUserMedia(如果存在)
            var 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)
            })
          }
        }
        var constraints = {
          audio: false,
          video: {width: this.videoWidth, height: this.videoHeight, transfORM: 'scaleX(-1)'}
        }
        navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
          // 旧的浏览器可能没有srcObject
          if ('srcObject' in _this.thisVideo) {
            _this.thisVideo.srcObject = stream
          } else {
            // 避免在新的浏览器中使用它,因为它正在被弃用。
            _this.thisVideo.src = window.URL.createObjectURL(stream)
          }
          _this.thisVideo.onloadedmetadata = function (e) {
            _this.thisVideo.play()
          }
        }).catch(err => {
          console.log(err)
        })
      },
      
      setImage() {
        var _this = this
        // 点击,canvas画图
        _this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight)
        // 获取图片base64链接
        var image = this.thisCancas.toDataURL('image/png')
        _this.imgSrc = image
        // console.log(_this.imgSrc)
        // this.$emit('refreshDataList', this.imgSrc)
      },
      
      dataURLtoFile(dataurl, filename) {
        var arr = dataurl.split(',')
        var mime = arr[0].match(/:(.*?);/)[1]
        var bstr = atob(arr[1])
        var n = bstr.length
        var u8arr = new Uint8Array(n)
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], filename, {type: mime})
      },
      
      stopNavigator() {
        this.thisVideo.srcObject.getTracks()[0].stop()
      },
      //上传图片
      setFileUpload() {
        //编辑档案-上传人脸照片
        if(this.deleteData) {
          if (this.deleteData.imagePath) {
            deleteFileUpload({id: this.deleteData.id, filePath: this.deleteData.imagePath})
              .then(res => {
                setFileUpload({image: this.imgSrc})
                  .then(res => {
                    this.$emit('fileUpload', res.retData.filePath, res.retData.imagePath)
                    addUserCard({userId: this.deleteData.userid, cardType: this.deleteData.cardType, userAuditInfo: res.retData.imagePath})
                      .then(res => {
                        this.$message({message: "上传成功", type: "success"})
                      })
                      .catch(err => {
                        console.log(err)
                      })
                  })
                  .catch(err => {
                    console.log(err)
                  })
              })
              .catch(err => {
                console.log(err)
              })
          } else {
            setFileUpload({image: this.imgSrc})
              .then(res => {
                this.$emit('fileUpload', res.retData.filePath, res.retData.imagePath)
                addUserCard({userId: this.deleteData.userid, cardType: this.deleteData.cardType, userAuditInfo: res.retData.imagePath})
                  .then(res => {
                    this.$message({message: "上传成功", type: "success"})
                  })
                  .catch(err => {
                    console.log(err)
                  })
              })
              .catch(err => {
                console.log(err)
              })
          }
        } else {
          //添加住户-上传人脸照片
          setFileUpload({image: this.imgSrc})
            .then(res => {
              // console.log(res)
              this.$message({message: "上传成功", type: "success"})
              this.$emit('fileUpload', res.retData.filePath, res.retData.imagePath)
            })
            .catch(err => {
              console.log(err)
            })
        }
      },
    },
    watch: {
      show(val) {
        if (val) {
          this.imgSrc = ``
          this.getCompetence()
        } else {
          this.stopNavigator()
        }
      },
    }
  }
</script>

<style lang="less">
  .camera-box {
    margin: 0 auto;
    text-align: center;

    .camera-p {
      height: 17px;
      line-height: 17px;
      font-size: 12px;
      font-family: "PingFang SC";
      font-weight: 400;
      color: rgba(154, 154, 154, 1);
      text-align: left;
    }

    .camera-btn {
      margin-top: 20px;
    }

  }
</style>

CameraDialog组件


<template>
  <div id="camera-dialog">
    <el-dialog
            title="拍摄照片"
            :visible.sync="dialogVisible"
            top="5vh"
            width="481px"
            @close="dialoGCancle"
            :close-on-click-modal="false"
            :before-close="dialogCancle"
    >
      <Camera :show="dialogVisible" :deleteData="deleteData" @fileUpload="fileUpload"></Camera>
      <span slot="footer" class="dialog-footer">
          <!-- <el-button @click="dialogCancle">取 消</el-button> -->
        <!-- <el-button type="primary">确 定</el-button> -->
        </span>
    </el-dialog>
  </div>
</template>

<script>
  import Camera from "@/page/house/Camera.vue"

  export default {
    name: 'CameraDialog',
    props: {
      dialogVisible: {type: Boolean},
      deleteData: {type: Object}
    },
    components: {
      Camera
    },
    data() {
      return {
        filePath: ``,
        imagePath: ``,
      }
    },
    methods: {
      //关闭弹窗
      dialogCancle() {
        this.$emit('dialogCancle', false, this.filePath, this.imagePath);
      },
      //获取人脸照片地址
      fileUpload(filePath, imagePath) {
        this.filePath = filePath
        this.imagePath = imagePath
        this.dialogCancle()
      }
    }
  }
</script>

<style scoped>
</style>

外部调用组件


<template>
  <div>
    <div class="form-thumb">
     <img :src="filePath" alt="">
      <i class="delete-btn" @click="deleteUploadFile" v-if="deleteData.imagePath">x</i>
    </div>
    <div class="upload-btn">
       <input type="file" name="userAuditInfo" id="userAuditInfo" @change="getUploadFile" ref="inputFile">
       <el-button type="defualt" size="small" @click="localUploadFile">本地上传</el-button>
       <el-button type="default" size="small" @click="dialogVisible=true">拍摄照片</el-button>
     </div>
    <!-- 拍摄照片弹窗 -->
    <CameraDialog :dialogVisible="dialogVisible" @dialogCancle="dialogCancleCamera" :deleteData="deleteData" />
  </div> 
</template>

<script>
  import CameraDialog from "./CameraDialog.vue"
  import { setFileUpload, deleteFileUpload, addUserCard } from "@/api/houseApi.js"
  export default {
    data() {
      return {
        filePath: require('@/assets/images/null.png'), //身份证头像
        dialogVisible: false,
        //操作删除人脸照片相关字段
        deleteData: {
          userid: this.$route.query.userId,
          id: ``,
          cardType: 4,
          imagePath: ``,
        }
   }
 },
 methods: {
      //模拟点击本地上传人脸照片
      localUploadFile() {
        this.$refs.inputFile.click()
      },
      //本地上传人脸照片
      getUploadFile() {
        let input = document.getElementById('userAuditInfo')
        let file = input.files[0]
        this.getBase64(file)
          .then(res => {
            if (this.deleteData.imagePath) {
              deleteFileUpload({id: this.deleteData.id, filePath: this.deleteData.imagePath})
                .then(() => {
                  this.setFileUpload(res)
                })
            } else {
              this.setFileUpload(res)
            }
          })
          .catch(err => {
            console.log(err)
          })
      },
      //上传人脸照片
      setFileUpload(res) {
        setFileUpload({image: res})
          .then(res => {
            this.filePath = res.retData.filePath
            this.deleteData.imagePath = res.retData.imagePath
            addUserCard({userId: this.deleteData.userid, cardType: this.deleteData.cardType, userAuditInfo: res.retData.imagePath})
              .then(res => {
                this.$message({message: res.retInfo, type: "success"})
                //用于更新数据,此方法未展示
                this.getInfo()
              })
              .catch(err => {
                console.log(err)
              })
          })
          .catch(err => {
            console.log(err)
          })
      },
      //转base64
      getBase64(file) {
        return new Promise(function (resolve, reject) {
          let reader = new FileReader();
          let imgResult = "";
          reader.readAsDataURL(file);
          reader.onload = function () {
            imgResult = reader.result;
          };
          reader.onerror = function (error) {
            reject(error);
          };
          reader.onloadend = function () {
            resolve(imgResult);
          };
        });
      },
      //删除人脸照片
      deleteUploadFile() {
        this.$confirm(`确认删除?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          deleteFileUpload({id: this.deleteData.id, filePath: this.deleteData.imagePath})
            .then(res => {
              this.$message({message: res.retInfo, type: "success"})
              this.filePath = require('@/assets/images/null.png')
              this.deleteData.imagePath = ''
            })
            .catch(err => {
              console.log(err)
            })
        }).catch(() => {});
      },
      //Dialog弹窗取消、获取上传人脸照片
      dialogCancleCamera(str, filePath, imagePath) {
        this.dialogVisible = str
        // this.houseInfo.filePath = filePath
        // this.houseInfo.userAuditInfo = imagePath
        this.filePath = filePath
        this.deleteData.imagePath = imagePath
        this.getInfo()
      }, 
 }
  }
</script> 

<style scoped="scoped">
  .upload-btn {
    position: relative;
    margin: 20px 12px 0 0;
    text-align: right;
  }
  input#userAuditInfo {
    position: absolute;
    display: inline-block;
    width: 80px;
    height: 32px;
    top: 0;
    cursor: pointer;
    font-size: 0;
    z-index: -1;
    
  }
  .delete-btn {
    position: absolute;
    top: -6px;
    right: -6px;
    display: inline-block;
    width: 16px;
    height: 16px;
    line-height: 14px;
    background: rgba(251, 135, 66, 1);
    border-radius: 8px;
    text-align: center;
    font-size: 12px;
    color: #fff;
    cursor: pointer;
  }
</style>

以上只作为实现参考,具体操作依实际需求做相应调整。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Vue调用PC摄像头实现拍照功能

本文链接: https://www.lsjlt.com/news/137160.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue调用PC摄像头实现拍照功能
    本文实例为大家分享了Vue调用PC摄像头实现拍照功能的具体代码,供大家参考,具体内容如下 项目需求:可以本地上传头像,也可以选择拍摄头像上传。 组件: 1、Camera组件:实现 打...
    99+
    2022-11-12
  • Vue实现调用PC端摄像头实时拍照
    Vue之调用PC端摄像头实时拍照,供大家参考,具体内容如下 由于我使用的是点击按钮打开模态框拍照所以在这里吧按钮和模态框代码都粘贴如下。 <!-- 打开模态框按钮--&g...
    99+
    2022-11-12
  • python调用摄像头实现拍照功能
    目录 1.介绍 2.系统依赖 (1)OpenCV-Python库 (2)Tkinter库 (3)Pillow库 (4)Time库 3.系统代码 4.效果展示 5.注意事项 1.介绍         这是一个有趣的项目,通过Python程...
    99+
    2023-09-21
    python 开发语言
  • vue调取电脑摄像头实现拍照功能
    本文实例为大家分享了vue调取电脑摄像头实现拍照功能的具体代码,供大家参考,具体内容如下 实现效果图: 拍照前&拍照后(我电脑摄像头挡住的,所以图片是灰色) 1.点击拍照上...
    99+
    2022-11-12
  • Java+OpenCV调用摄像头实现拍照功能
    目录环境准备制作主界面整体结构介绍核心代码与知识点讲解JPanel中如何显示摄像头的图像OpenCV调用摄像头使用摄像头拍照完整代码OpenCVUtil.javaImageUtils...
    99+
    2022-11-13
  • Python实现调用摄像头拍摄照片
    目录步骤代码实现效果步骤 用opencv打开摄像头并拍照保存照片到本地获取邮箱(如qq邮箱)的授权码,方法可自行百度将照片以附件的形式发送到指定邮箱删除本地照片 代码 import ...
    99+
    2022-11-11
  • 怎么用Java+OpenCV调用摄像头实现拍照功能
    这篇文章主要介绍了怎么用Java+OpenCV调用摄像头实现拍照功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Java+OpenCV调用摄像头实现拍照功能文章都会有所收获,下面我们一起来看看吧。环境准...
    99+
    2023-06-29
  • 微信小程序调用摄像头实现拍照功能
    本文实例为大家分享了微信小程序调用摄像头实现拍照的具体代码,供大家参考,具体内容如下 微信小程序开发文档 首先,需要用户授权摄像头权限,这一步是必须的 具体步骤: 1、获取用户当前授...
    99+
    2022-11-13
  • 怎么用HTML5实现调用手机摄像头拍照功能
    本篇内容介绍了“怎么用HTML5实现调用手机摄像头拍照功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2022-10-19
  • Python如何实现调用摄像头拍摄照片
    本文小编为大家详细介绍“Python如何实现调用摄像头拍摄照片”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python如何实现调用摄像头拍摄照片”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。步骤用opencv...
    99+
    2023-07-02
  • Android调用手机摄像头拍照和录音功能
    本文实例为大家分享了Android调用手机摄像头拍照和录音功能的具体代码,供大家参考,具体内容如下 调用摄像头拍照: public class MainActivity extend...
    99+
    2022-11-13
  • Android实现调用摄像头拍照并存储照片
    目录1、前期准备2、主要方法1、需要使用Intent调用摄像头2、需要检查SD卡(外部存储)状态3、获取图片及其压缩图片3、案例展示1、Layout2、MainActivity1、前...
    99+
    2022-11-12
  • python实现调用摄像头并拍照发邮箱
    项目地址: https://github.com/flygaga/camera 思路 通过opencv调用摄像头拍照保存图像到本地 用email库构造邮件内容,保存图片以附件形式插入邮件内容 用smtplib库发送...
    99+
    2022-06-02
    python 调用摄像头 python 拍照发邮件 python 摄像头拍照
  • 如何使用HTML5实现超酷摄像头拍照功能
    这篇文章给大家分享的是有关如何使用HTML5实现超酷摄像头拍照功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。WebRTC可能是明年最受关注的HTML5标准了,Mozilla为...
    99+
    2022-10-19
  • Androidstudio调用摄像头拍照并保存照片
    本文实例为大家分享了Androidstudio调用摄像头拍照并保存照片的具体代码,供大家参考,具体内容如下 首先在manifest.xmlns文件中声明权限 <xml vers...
    99+
    2022-11-13
  • Android中怎么调用摄像头拍照
    本篇文章给大家分享的是有关Android中怎么调用摄像头拍照,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。第一步,获取权限if (ContextCompat.chec...
    99+
    2023-06-04
  • Android实现控制摄像头拍照
    现在的手机一般都会提供相机功能,有些相机的镜头甚至支持1300万以上像素,有些甚至支持独立对焦、光学变焦这些只有单反才有的功能,甚至有些手机直接宣传可以拍到星星。可以说手机已经变成了...
    99+
    2022-11-13
  • Android怎么调用手机摄像头拍照和录音功能
    本文小编为大家详细介绍“Android怎么调用手机摄像头拍照和录音功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android怎么调用手机摄像头拍照和录音功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。调...
    99+
    2023-06-29
  • vue实现pc端拍照上传功能
    本文实例为大家分享了vue实现pc端拍照上传功能的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html>   <hea...
    99+
    2022-11-12
  • python怎么实现调用摄像头并拍照发邮箱
    这篇文章主要介绍了python怎么实现调用摄像头并拍照发邮箱,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。python的五大特点是什么python的五大特点:1.简单易学,开...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作