vue 连接高拍仪实现pc 端拍照上传功能
需求描述:实现电脑拍照内置摄像头拍照和连接高拍仪外置摄像头拍照。实现原理:利用H5 调用浏览器的摄像头来实现视频功能,然后利用canvas 截图,把当前的屏幕截取,生成一张图片。注意事项:电脑有内置的摄像头,也有外接的高拍仪,所以需要获取到全部的,然后可以选择切换摄像头。打开弹窗时会默认获取所有的摄像头,并且默认选择第一个,然后打开摄像头。点击确定时会生成一张图片。然后拿到图片就可以调取接口了。效
·
需求描述:实现电脑拍照内置摄像头拍照和连接高拍仪外置摄像头拍照。
实现原理:利用H5 调用浏览器的摄像头来实现视频功能,然后利用canvas 截图,把当前的屏幕截取,生成一张图片。
注意事项:电脑有内置的摄像头,也有外接的高拍仪,所以需要获取到全部的,然后可以选择切换摄像头。
打开弹窗时会默认获取所有的摄像头,并且默认选择第一个,然后打开摄像头。点击确定时会生成一张图片。然后拿到图片就可以调取接口了。
效果如下:
以下为拍照子组件代码:
里面有一点点数据是业务数据,可自行去掉。
<template>
<el-dialog
width="50%"
title="拍照"
:before-close="closeCamera"
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
:visible.sync="innerVisible"
append-to-body>
<div class="camera-content">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="">
<el-input v-model="form.eyes"></el-input>
</el-form-item>
<el-form-item label="">
<el-input v-model="form.remark"></el-input>
</el-form-item>
<el-form-item label="摄像头">
<el-select v-model="camera"
style="width: 100%"
@change="handleChange"
placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
<!--开启摄像头-->
<!-- <img @click="callCamera" :src="headImgSrc" alt="摄像头">-->
<!-- canvas截取流-->
<canvas v-show="false" ref="canvas" width="640" height="480"></canvas>
<!-- 图片展示-->
<video ref="video" width="640" height="480" autoplay></video>
<!--确认-->
<el-button size="mini" type="primary" @click="photograph">确定</el-button>
<el-button size="mini" type="primary" @click="handleClose">关闭</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'CameraUpload',
props: {
innerVisible: {
type: Boolean,
default: false,
},
rowData: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
form: {
eyes: '',
remark: '',
},
headImgSrc: '',
dialogCamera: false,
camera: '',
options: [],
}
},
mounted() {
// this.getAllCamera();
},
methods: {
handleClose() {
this.closeCamera();
this.$emit('closeCamera');
},
handleChange(val) {
this.closeCamera();
this.camera = val;
this.callCamera()
},
// 获取摄像头
getAllCamera() {
navigator.mediaDevices.enumerateDevices()
.then(this.gotDevices).then(this.callCamera).catch(this.handleError);
},
handleError(error) {
this.$message.error(error.name + ": " + error.message)
},
gotDevices(deviceInfos) {
console.log(deviceInfos);
this.options = [];
for (var i = 0; i < deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
this.options.push({
value: deviceInfo.deviceId,
label: deviceInfo.label
})
} else {
console.log('Found ome other kind of source/device: ', deviceInfo);
}
}
this.camera = this.options[0].value;
},
// 调用摄像头
callCamera() {
// this.getAllCamera();
// H5调用电脑摄像头API
navigator.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('摄像头开启失败,请检查摄像头是否可用并重新打开!')
})
},
// 拍照
photograph() {
let ctx = this.$refs['canvas'].getContext('2d')
// 把当前视频帧内容渲染到canvas上
ctx.drawImage(this.$refs['video'], 0, 0, 640, 480)
// 转base64格式、图片格式转换、图片质量压缩
let imgBase64 = this.$refs['canvas'].toDataURL('image/jpeg', 0.7)
console.log(imgBase64);
// 由字节转换为KB 判断大小
let str = imgBase64.replace('data:image/jpeg;base64,', '')
let strLength = str.length
let fileLength = parseInt(strLength - (strLength / 8) * 2)
// 图片尺寸 用于判断
let size = (fileLength / 1024).toFixed(2)
console.log(size)
// 上传拍照信息 调用接口上传图片 .........
// 保存到本地
// this.dialogCamera = false
// let ADOM = document.createElement('a')
// ADOM.href = this.headImgSrc
// ADOM.download = new Date().getTime() + '.jpeg'
// ADOM.click()
},
// 关闭摄像头
closeCamera() {
if (!this.$refs['video'].srcObject) {
this.dialogCamera = false
return
}
let stream = this.$refs['video'].srcObject
let tracks = stream.getTracks()
tracks.forEach(track => {
track.stop()
})
this.$refs['video'].srcObject = null;
// this.$emit('closeCamera')
},
}
}
</script>
<style lang="less" scoped>
.camera-content {
text-align: center;
}
</style>
以下为父组件引用代码:
一些业务逻辑代码可自行去掉
<CameraUpload
:rowData="rowData"
@closeCamera="closeCamera"
:innerVisible="innerVisible"
ref="myCameraUpload"/>
handleCamera() {
this.innerVisible = true;
this.$nextTick(() => {
this.$refs.myCameraUpload.getAllCamera();
})
},
closeCamera() {
this.innerVisible = false;
this.getUploadList();
},
更多推荐
已为社区贡献2条内容
所有评论(0)