項目背景:
用 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>
export default {
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點多 ==||
