日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > vue >内容正文

vue

Vue 调用PC摄像头拍照

發(fā)布時(shí)間:2024/3/26 vue 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue 调用PC摄像头拍照 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

項(xiàng)目需求:可以本地上傳頭像,也可以選擇拍攝頭像上傳。

組件:

  • Camera組件:實(shí)現(xiàn) 打開(kāi)、關(guān)閉攝像頭、繪制、顯示圖片、用于上傳
  • CameraDialog組件:使用ElementUI dialog組件 展示攝像頭UI效果
  • 外部調(diào)用CameraDialog組件,實(shí)現(xiàn)拍攝頭像上傳功能
  • 本地上傳可使用原生input、也可使用ElementUI upload組件
  • 操作邏輯:

  • 新增時(shí)將頭像圖片轉(zhuǎn)為base64調(diào)用接口提交,返回url地址用于前端展示
  • 替換時(shí),先執(zhí)行刪除操作,在依新增操作執(zhí)行。
  • 本地上傳原理跟拍攝上傳一致
  • 具體實(shí)現(xiàn)方法:

    • 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?'提示:請(qǐng)將頭像居中按"拍照"鍵確認(rèn)':''}}</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彈窗顯示狀態(tài)show: {type: Boolean},//【可選】配合原生input本地上傳,用于替換時(shí)執(zhí)行刪除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 調(diào)用權(quán)限*****************************************/getCompetence() {var _this = thisthis.thisCancas = document.getElementById('canvas')this.thisContext = this.thisCancas.getContext('2d')this.thisVideo = document.getElementById('video')// 舊版本瀏覽器可能根本不支持mediaDevices,我們首先設(shè)置一個(gè)空對(duì)象if (navigator.mediaDevices === undefined) {navigator.mediaDevices = {}}// 一些瀏覽器實(shí)現(xiàn)了部分mediaDevices,我們不能只分配一個(gè)對(duì)象// 使用getUserMedia,因?yàn)樗鼤?huì)覆蓋現(xiàn)有的屬性。// 這里,如果缺少getUserMedia屬性,就添加它。if (navigator.mediaDevices.getUserMedia === undefined) {navigator.mediaDevices.getUserMedia = function (constraints) {// 首先獲取現(xiàn)存的getUserMedia(如果存在)var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia// 有些瀏覽器不支持,會(huì)返回錯(cuò)誤信息// 保持接口一致if (!getUserMedia) {return Promise.reject(new Error('getUserMedia is not implemented in this browser'))}// 否則,使用Promise將調(diào)用包裝到舊的navigator.getUserMediareturn 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) {// 舊的瀏覽器可能沒(méi)有srcObjectif ('srcObject' in _this.thisVideo) {_this.thisVideo.srcObject = stream} else {// 避免在新的瀏覽器中使用它,因?yàn)樗诒粭売谩?/span>_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 繪制圖片*****************************************/setImage() {var _this = this// 點(diǎn)擊,canvas畫(huà)圖_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)},/**@author Brady*@Time 2019/9/5*@function base64轉(zhuǎn)文件*****************************************/dataURLtoFile(dataurl, filename) {var arr = dataurl.split(',')var mime = arr[0].match(/:(.*?);/)[1]var bstr = atob(arr[1])var n = bstr.lengthvar 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 關(guān)閉攝像頭*****************************************/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-dialogtitle="拍攝照片":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: {//關(guān)閉彈窗dialogCancle() {this.$emit('dialogCancle', false, this.filePath, this.imagePath);},//獲取人臉照片地址fileUpload(filePath, imagePath) {this.filePath = filePaththis.imagePath = imagePaththis.dialogCancle()}}} </script><style scoped> </style>
    • 外部調(diào)用組件
    <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,//操作刪除人臉照片相關(guān)字段deleteData: {userid: this.$route.query.userId,id: ``,cardType: 4,imagePath: ``,}}},methods: {//模擬點(diǎn)擊本地上傳人臉照片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.filePaththis.deleteData.imagePath = res.retData.imagePathaddUserCard({userId: this.deleteData.userid, cardType: this.deleteData.cardType, userAuditInfo: res.retData.imagePath}).then(res => {this.$message({message: res.retInfo, type: "success"})//用于更新數(shù)據(jù),此方法未展示this.getInfo()}).catch(err => {console.log(err)})}).catch(err => {console.log(err)})},//轉(zhuǎn)base64getBase64(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(`確認(rèn)刪除?`, '提示', {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 = imagePaththis.filePath = filePaththis.deleteData.imagePath = imagePaththis.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>

    以上只作為實(shí)現(xiàn)參考,具體操作依實(shí)際需求做相應(yīng)調(diào)整

    總結(jié)

    以上是生活随笔為你收集整理的Vue 调用PC摄像头拍照的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。