Vue實現網頁線上拍照和上傳
專案背景:
用 vue-cli + element-ui 開發的專案
方法一(不支援360相容模式、IE):使用mediaDevices.getUserMedia()
程式碼如下:
<template> <div class="take-photo"> <!-- 拍照 --> <video id="videoCamera" :width="videoWidth" :height="videoHeight" autoPlay></video> <el-button size="small" type="primary" @click="takePhotoHandle">拍照</el-button> <!-- 預覽 --> <canvas id="canvasCamera" :width="videoWidth" :height="videoHeight"></canvas> <el-button size="small" type="primary" :loading="loading" @click="uploadHandle">上傳</el-button> </div> </template> <script> exportdefault { name: 'takePhoto', data () { return { loading: false, // 上傳照片的loading imgSrc: "", // 照片地址 photoVideo: null, // 拍照框 photoContext: null, // canvas繪圖環境 photoCancas: null, // 預覽框 videoWidth: 306, // 拍照框寬度 videoHeight: 378, // 拍照框高度 } }, mounted () {// 開啟攝像頭 this.openCamera() }, beforeDestroy() { if (this.photoVideo && this.photoVideo.srcObject) { // 停止視訊流 this.photoVideo.srcObject.getTracks()[0].stop(); } }, methods: { // 拍照處理 takePhotoHandle () { // canvas畫圖 this.photoContext.drawImage(this.photoVideo, 0, 0, this.videoWidth, this.videoHeight) // 獲取圖片base64連結 this.imgSrc = this.photoCancas.toDataURL('image/png') }, // 開啟攝像頭 async openCamera() { this.photoVideo = document.getElementById('videoCamera') this.photoCancas = document.getElementById('canvasCamera') this.photoContext = this.photoCancas.getContext('2d') try { const constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight } } const stream = await navigator.mediaDevices.getUserMedia(constraints) this.photoVideo.srcObject = stream this.photoVideo.play() } catch (error) { this.$message({ title: '警告', message: '請確認攝像頭能正常工作,必須使用谷歌瀏覽器或者360瀏覽器的極速模式,否則拍照不能正常使用', type: 'warning', duration: 8000 }); } }, // 上傳照片 async uploadHandle () { this.loading = true try { const firstIndex = this.imgSrc.indexOf('base64,') const url = this.imgSrc.substr(firstIndex + 7) const params = { photo: url } // 傳送介面 await xxx(params) this.loading = false } catch (error) { this.loading = false } } } } </script> <style lang="scss" scoped> </style>
方法二(相容360相容模式、IE):使用webcamjs
實現步驟:
1、安裝適合瀏覽器的flash:https://www.flash.cn/download-wins
為了相容IE,我下載的是下圖版本:
2、將webcam.min.js 和webcam.swf 檔案,放到根目錄——>public目錄中。
這兩個檔案可以在 webcamjs的github上拿到:https://github.com/jhuckaby/webcamjs
3、public目錄下的index.html,在頭部引入webcam.min.js。
4、takePhoto.vue是拍照頁,其中程式碼如下:
<template> <div class="take-photo"> <!-- 拍照 --> <div id="photoCamera"></div> <el-button size="small" type="primary" @click="takePhotoHandle">拍照</el-button> <!-- 預覽 --> <div id="imageCamera"></div> <el-button size="small" type="primary" :loading="loading" @click="uploadHandle">上傳</el-button> </div> </template> <script> export default { name: 'takePhoto', data () { return { loading: false, // 上傳照片的loading imgSrc: "", videoWidth: 306, videoHeight: 378, } }, mounted () { Webcam.set({ width: this.videoWidth, height: this.videoHeight, image_format: 'jpeg', jpeg_quality: 100, swfURL: '../../webcam.swf', // 指定swf檔案 }) Webcam.attach('#photoCamera') }, methods: { // 拍照處理 takePhotoHandle () { Webcam.snap(url => { this.imgSrc = url document.getElementById('imageCamera').innerHTML = `<img src="${url}">` }) }, // 上傳照片 async uploadHandle () { this.loading = true try { const firstIndex = this.imgSrc.indexOf('base64,') const url = this.imgSrc.substr(firstIndex + 7) const params = { photo: url } // 調介面 await xxx(params) this.loading = false } catch (error) { this.loading = false } }, } } </script> <style lang="scss" scoped> </style>
使用方法二時,注意 && 補充:
1、安裝完 flash 後,當瀏覽器訪問拍照頁面時,會彈出下圖提示,選擇 一鍵開啟。
2、前端框架開發的專案,Webcam.set 中的swfURL 配置很重要。
swfURL:配置webcam.swf的檔案路徑。
測試是否設定成功:在瀏覽器中,要能訪問到這個檔案。
比如我把swf檔案放在根目錄——>public目錄下,拍照的訪問地址是http://localhost/student/photo/takePhoto
那麼swfURL設定為 "../../webcam.swf"。當訪問http://localhost/webcam.swf,是可以訪問到這個swf檔案的。
這個swf很重要,訪問不到的話,就會出現:明明有了flash,但拍照框裡一片空白。因為這個swf就是詢問你是否願意開啟攝像頭的,允許了才可以開啟攝像頭。
這個swf就是下面這個檔案:
3、如何不用詢問,直接開啟攝像頭呢?
拍照畫面,滑鼠右鍵——>設定,開啟下圖,勾選“允許”和“記住”。
想了解詳細的話,可以點選彈窗右上角的 “?” 檢視。
4、參考資料:
webcamjs的github地址:https://github.com/jhuckaby/webcamjs
webcamjs支援h5以及flash的方式呼叫攝像頭:https://www.zybuluo.com/Fancy-Bai/note/725731
webcamjs的中文簡介:https://crazyhuiliang.gitbooks.io/javascript/content/WebcamJS.html
背後心得:
現在解決了,便會覺得也沒啥大不了。但遇到問題的當時,真的是很頭疼。
每次聽到要在IE上用,頭都大了,白眼翻到九霄雲外。
一開始以為是flash的問題,裝了卸,卸了裝,搞了一天。後來遇到空白的問題,都要放棄了,
後端小夥伴說放棄吧,換個方法吧,研究下ActiveX拍照控制元件。
What ? NONONO,花了這麼久捯飭,不給個結果,對不起掉的頭髮。總感覺真相就隔著一層紙。
結果真的找到了swf這個原因,攝像頭開啟的時候,眼淚都要出來了。
測試容易走神:總是看到低畫質無美顏的大臉,心情都糟了。
上一篇部落格是兩年多前,現在逼著自己把這個整理了,短短的文章,竟然也從1點多寫到4點多 ==||