1.子组件(高拍仪的拍照和上传服务器)
<template><div class="photoClass"><div class="upPhotoClass" @click="upPhotoFn" /><el-dialog :visible.sync="dialogVisible" :modal="false" width="30%" :show-close="false"><canvas v-show="false" ref="canvas" width="400" height="400" /><video ref="video" width="400" height="400" autoplay /><span slot="footer" class="dialog-footer"><el-button @click="handleClose">取 消</el-button><el-button type="primary" @click="photograph">确 定</el-button></span></el-dialog></div>
</template><script>
import { apiUpload } from '@/api/index.js'
export default {props: {edits: {type: Boolean,default: true}},data() {return {dialogVisible: false,camera: '',imgSrc: ''}},computed: {},methods: {//点击弹出高拍仪摄像头upPhotoFn() {if (!this.edits) {//是否可以点开dialogreturn}this.dialogVisible = truethis.getAllCamera()},handleClose() {this.closeCamera()this.dialogVisible = false},// 获取摄像头getAllCamera() {navigator.mediaDevices.enumerateDevices().then(this.gotDevices).then(this.callCamera).catch(this.handleError)},// 选择摄像头gotDevices(deviceInfos) {console.log(deviceInfos)const options = []for (var i = 0; i < deviceInfos.length; ++i) {var deviceInfo = deviceInfos[i]var option = document.createElement('option')option.value = deviceInfo.deviceIdif (deviceInfo.kind === 'videoinput') {options.push({value: deviceInfo.deviceId,label: deviceInfo.label})} else {// console.log('Found ome other kind of source/device: ', deviceInfo);}}this.camera = options[1].value//options[1]高拍仪第二个摄像头,第一个写为options[0]},// 调用摄像头错误handleError(error) {this.$message.error(error.name + ': ' + error.message)},// 调用摄像头callCamera() {// this.getAllCamera();// H5调用电脑摄像头APInavigator.mediaDevices.getUserMedia({// video: true,video: {optional: [{sourceId: this.camera}]}}).then(success => {// console.log(success);// 摄像头开启成功this.$refs['video'].srcObject = success// 实时拍照效果this.$refs['video'].play()}).catch(error => {this.$message.error('摄像头开启失败,请检查摄像头是否可用并重新打开!')})},// 关闭摄像头closeCamera() {if (!this.$refs['video'].srcObject) {this.dialogVisible = falsereturn}const stream = this.$refs['video'].srcObjectconst tracks = stream.getTracks()tracks.forEach(track => {track.stop()})this.$refs['video'].srcObject = null// this.$emit('closeCamera')},//拍照photograph() {const ctx = this.$refs['canvas'].getContext('2d')// 把当前视频帧内容渲染到canvas上ctx.drawImage(this.$refs['video'], 0, 0, 400, 400)// 转base64格式、图片格式转换、图片质量压缩// let imgBase64 = this.$refs['canvas'].toDataURL('image/jpeg', 0.7)const imgurl = this.$refs['canvas'].toDataURL('image/png')this.imgSrc = imgurlconsole.log(imgurl)this.onUpload()},onUpload() {const file = this.imgSrc // 把整个base64给fileconst time = new Date().valueOf() // 生成时间戳const name = time + '.png' // 定义文件名字(例如:abc.png , cover.png)const conversions = this.dataURLtoFile(file, name) // 调用base64转图片方法const data = new FormData()data.append('file', conversions)apiUpload(data).then(res => {//上传到服务console.log(res)if (res.code == 200) {this.$emit('changPhotoFn', res.data)//返回值传给父组件}}).catch((e) => {console.log(e)})this.closeCamera()this.dialogVisible = false},// base64转文件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 })}}
}
</script><style scoped>
.photoClass {width: 120px;height: 120px;
}
.upPhotoClass {width: 100%;height: 100%;border: 1px dotted #d9d9d9;
}
.photoDialogClass {/* height: 300px; */
}
</style>
2.父组件