Vue calls the PC camera to realize the photo function

Vue calls the PC camera to realize the photo function

This article example shares the specific code of Vue calling the PC camera to realize the photo function for your reference. The specific content is as follows

Project requirements: You can upload the avatar locally, or you can choose to take a photo and upload it.

Components:

1. Camera component: realize opening and closing the camera, drawing, displaying pictures, and uploading
2. CameraDialog component: Use ElementUI dialog component to display camera UI effect
3. Call the CameraDialog component externally to realize the function of uploading the portrait
4. Local upload can use native input or ElementUI upload component

Operation logic:

1. When adding, convert the avatar image to base64 and submit it to the calling interface, and return the URL address for front-end display
2. When replacing, first perform the delete operation, and then perform the add operation.
3. The principle of local upload is the same as that of shooting upload

Specific implementation method:

Camera Component

<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?'Tip: Please center the avatar and press the "photo" button to confirm':''}}</p>
    <el-button type="primary" @click="setImage" v-if="!imgSrc" class="camera-btn">Take a photo</el-button>
    <el-button type="primary" v-if="imgSrc" @click="setFileUpload" class="camera-btn">Upload</el-button>
  </div>
</template>

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

  export default {
    name: 'Camera',
    props: {
      //【Required】CameraDialog pop-up window display status show: {type: Boolean},
      //[Optional] Use native input for local upload to delete when replacing deleteData: {type: Object}
    },
    data() {
      return {
        videoWidth: '401',
        videoHeight: '340',
        thisCancas: null,
        thisContext: null,
        thisVideo: null,
        imgSrc: ``,
      }
    },
    mounted() {
      if (this.show) this.getCompetence()
    },
    methods: {
      /*
       *@author Brady
       *@Time 2019/9/5
       *@function calling permission*********************************************/
      getCompetence() {
        var _this = this
        this.thisCancas = document.getElementById('canvas')
        this.thisContext = this.thisCancas.getContext('2d')
        this.thisVideo = document.getElementById('video')
        // Older browsers may not support mediaDevices at all, so we first set an empty object if (navigator.mediaDevices === undefined) {
          navigator.mediaDevices = {}
        }
        // Some browsers implement partial mediaDevices, and we can't just assign an object // using getUserMedia because it will overwrite existing properties.
        // Here, if the getUserMedia property is missing, add it.
        if (navigator.mediaDevices.getUserMedia === undefined) {
          navigator.mediaDevices.getUserMedia = function (constraints) {
            // First get the existing getUserMedia (if it exists)
            var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
            // Some browsers do not support it and will return an error message // Keep the interface consistent if (!getUserMedia) {
              return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
            }
            // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
            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) {
          // Old browsers may not have srcObject
          if ('srcObject' in _this.thisVideo) {
            _this.thisVideo.srcObject = stream
          } else {
            // Avoid using this in newer browsers as it is being deprecated.
            _this.thisVideo.src = window.URL.createObjectURL(stream)
          }
          _this.thisVideo.onloadedmetadata = function (e) {
            _this.thisVideo.play()
          }
        }).catch(err => {
          console.log(err)
        })
      },
      /*
       *@author Brady
       *@Time 2019/9/5
       *@function draw picture*********************************************/
      setImage() {
        var _this = this
        // Click, canvas drawing_this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight)
        // Get the base64 link of the image var image = this.thisCancas.toDataURL('image/png')
        _this.imgSrc = image
        // console.log(_this.imgSrc)
        // this.$emit('refreshDataList', this.imgSrc)
      },
      /*
       *@author Brady
       *@Time 2019/9/5
       *@function base64 convert file********************************************/
      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})
      },
      /*
       *@author Brady
       *@Time 2019/9/5
       *@function Close the camera*********************************************/
      stopNavigator() {
        this.thisVideo.srcObject.getTracks()[0].stop()
      },
      //Upload picture setFileUpload() {
        //Edit file - upload face photo 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: "Upload successful", 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: "Upload successful", type: "success"})
                  })
                  .catch(err => {
                    console.log(err)
                  })
              })
              .catch(err => {
                console.log(err)
              })
          }
        } else {
          //Add resident - upload face photo setFileUpload({image: this.imgSrc})
            .then(res => {
              // console.log(res)
              this.$message({message: "Upload successful", 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 Component

<template>
  <div id="camera-dialog">
    <el-dialog
            title="Take a photo"
            :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">Cancel</el-button> -->
        <!-- <el-button type="primary">OK</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: {
      //Close the pop-up window dialogCancle() {
        this.$emit('dialogCancle', false, this.filePath, this.imagePath);
      },
      //Get the address of the face photo fileUpload(filePath, imagePath) {
        this.filePath = filePath
        this.imagePath = imagePath
        this.dialogCancle()
      }
    }
  }
</script>

<style scoped>
</style>

External call component

<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">Local upload</el-button>
       <el-button type="default" size="small" @click="dialogVisible=true">Take a photo</el-button>
     </div>
    <!-- Pop-up window for taking photos-->
    <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'), //ID card avatar dialogVisible: false,
        //Operation to delete face photo related fields deleteData: {
          userid: this.$route.query.userId,
          id: ``,
          cardType: 4,
          imagePath: ``,
        }
   }
 },
 methods: {
      //Simulate clicking to upload a face photo locallylocalUploadFile() {
        this.$refs.inputFile.click()
      },
      //Local upload face photo 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)
          })
      },
      //Upload face photo 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"})
                //Used to update data, this method does not show this.getInfo()
              })
              .catch(err => {
                console.log(err)
              })
          })
          .catch(err => {
            console.log(err)
          })
      },
      //Convert to 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);
          };
        });
      },
      //Delete face photo deleteUploadFile() {
        this.$confirm(`Confirm deletion?`, 'prompt', {
          confirmButtonText: 'Confirm',
          cancelButtonText: 'Cancel',
          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(() => {});
      },
      //Cancel the Dialog pop-up window and get the uploaded face photo 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;
    /*opacity: 0;*/
  }
  .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>

The above is only for reference. The specific operations should be adjusted according to actual needs.

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Vue implements calling PC camera to take photos in real time
  • Vue calls the computer camera to realize the photo function
  • Vue calls the local camera to realize the photo function
  • Vue2.0 implements the function of calling the camera to take pictures, and exif.js implements the picture upload function
  • Vue calls the camera to take pictures and save them locally

<<:  Modify the default data directory of MySQL 8.0 (quick operation without configuration)

>>:  Solution to the 404/503 problem when logging in to TeamCenter12

Recommend

Implementing a web player with JavaScript

Today I will share with you how to write a player...

An article tells you how to write a Vue plugin

Table of contents What is a plugin Writing plugin...

CentOS 7.5 deploys Varnish cache server function

1. Introduction to Varnish Varnish is a high-perf...

Learn the common methods and techniques in JS arrays and become a master

Table of contents splice() Method join() Method r...

Vue3.0 handwritten carousel effect

This article shares the specific code of Vue3.0 h...

Nginx URL rewriting mechanism principle and usage examples

URL rewriting helps determine the preferred domai...

Example of writing mobile H5 to invoke APP (IOS, Android)

iOS 1. URL scheme This solution is basically for ...

Tutorial on building an FTP server in Ubuntu 16.04

Ubuntu 16.04 builds FTP server Install ftp Instal...

Let you understand the working principle of JavaScript

Table of contents Browser kernel JavaScript Engin...

How to click on the a tag to pop up the input file upload dialog box

html Copy code The code is as follows: <SPAN cl...

Example of configuring multiple SSL certificates for a single Nginx IP address

By default, Nginx supports only one SSL certifica...

How to use boost.python to call c++ dynamic library in linux

Preface Recently I started using robot framework ...

4 functions implemented by the transform attribute in CSS3

In CSS3, the transform function can be used to im...