近来在写一个公众号的项目,因为开发需求,需要调取手机摄像头拍照。最重要的是要有遮罩层,这就限制了不能调用手机自带的摄像头。
项目框架是vue-cli,中间查了很多资料,有用原生js写的(虽然就是用navigator.mediaDevices.getUserMedia,但还是感觉有些麻烦)
也有用一些组件的(说的好用,但都不好用)总之就是查了很久,试了好多坑,最后偶然看到了这个组件
easy-vue-camera
地址:https://www.npmjs.com/package/easy-vue-camera
也不是说很完美很好用,但比之其他(指一些已经早已不在维护的组件、插件)还是好用的多
官方的组件截图长这样:
但因为需求要拍照人脸,遮罩层则是这样:
插件的文档里有写遮罩层的配置项,但不是常显在页面上的,点击会显示、隐藏切换,这肯定是不行的!
所以为了达成目的真的是不择手段啦!
上代码:
<template>
<div>
<v-easy-camera
:fullscreen="true"
ref="easyCamera"
v-model="pictureData.picture"
>
<template #header>
<div class="top">
<van-image
class="mask_control_close"
width="20px"
height="20px"
fit="cover"
@click="cameraStop"
:src="require('../../../public/img/camera_close.png')"
/>
</div>
</template>
</v-easy-camera>
<van-image
class="mask"
fit="fill"
:src="require('../../../public/img/camera_mask.png')"
/>
<van-image
class="mask_control"
width="80px"
height="80px"
fit="cover"
@click="cameraSnap"
:src="require('../../../public/img/camera_btn.png')"
/>
<van-image
v-show="confirmIsShow"
class="mask_control_confirm"
width="30px"
height="30px"
fit="cover"
@click="confirm"
:src="require('../../../public/img/camera_confirm.png')"
/>
<van-image
v-show="confirmIsShow"
class="mask_control_return"
width="30px"
height="30px"
fit="cover"
@click="cancel"
:src="require('../../../public/img/camera_return.png')"
/>
</div>
</template>
<script>
import EasyCamera from "easy-vue-camera";
export default {
name: "cameraCustom",
components: {
"v-easy-camera": EasyCamera,
},
data() {
return {
pictureData: {
picture: "",
pictureSize: "",
},
isEnable: true,
myEasyCamera: null,
confirmIsShow: false,
};
},
mounted() {
//获取原始控件区并隐藏(处理为移除子元素)
let aaa = document.getElementsByClassName("camera-stack")[0];
let div = document.createElement("div");
div.className = "bott";
div.style.height = "60px";
div.style.widht = "100%";
aaa.appendChild(div);
let controlModel = document.getElementsByClassName(
"camera-stack-controls"
)[0];
controlModel.removeChild(controlModel.firstChild);
//获取拍照组件实例
this.myEasyCamera = this.$refs.easyCamera;
},
methods: {
// 点击关闭
cameraStop() {
// console.log("关闭");
this.myEasyCamera.close();
this.$emit("close");
},
// 点击拍照
cameraSnap() {
if (!this.isEnable) {
return;
}
// console.log("拍照");
this.myEasyCamera.snap();
document.getElementsByClassName(
"camera-stack-controls"
)[0].style.display = "none";
this.confirmIsShow = true;
this.pictureData.pictureSize =
this.getImageSize(this.pictureData.picture) / 1024 / 1024;
this.isEnable = false;
},
// 点击对号完成
confirm() {
// console.log("完成");
this.isEnable = true;
this.confirmIsShow = false;
this.$emit("setPictureUrl", this.pictureData);
this.$emit("close");
},
// 点击返回重拍
cancel() {
// console.log("重拍");
this.isEnable = true;
this.confirmIsShow = false;
this.myEasyCamera.start();
},
// 获取照片大小
getImageSize(base64Str) {
const indexBase64 = base64Str.indexOf("base64,");
if (indexBase64 < 0) return false;
const str = base64Str.substr(indexBase64 + 6);
return (str.length * 0.75).toFixed(2);
},
},
};
</script>
<style lang="scss" scoped>
.top {
background-color: black;
height: 100px;
width: 100%;
}
.bott {
position: absolute;
background-color: black;
width: 100%;
z-index: 18;
}
.mask {
position: absolute;
top: 90px;
z-index: 18;
height: calc(100% - 138px);
}
.mask_control {
position: absolute;
z-index: 18;
left: calc(50% - 40px);
bottom: 40px;
}
.mask_control_close {
position: absolute;
z-index: 18;
right: 20px;
top: 20px;
}
.mask_control_confirm {
position: absolute;
z-index: 18;
right: 40px;
bottom: 60px;
}
.mask_control_return {
position: absolute;
z-index: 18;
left: 40px;
bottom: 60px;
}
</style>
以上代码就是用 easy-vue-camera 封装的一个拍照组件,其中图片替换成自己需要的就好,页面嘛就长这样:
用到这个组件的代码:
<!-- 拍照组件 -->
<cameraCustom
@close="cameraCustomIsShow = false"
@setPictureUrl="cameraProtrait"
v-if="cameraCustomIsShow"
></cameraCustom>
这里用vue的事件总线来完成组件间的通信
这就完成了 浏览器调取手机摄像头拍照并有遮罩层 其实还是比较容易的。
这样写出来,给自己记录下,也给有需要的人一点帮助。如有转发请标注原文地址https://blog.csdn.net/Bai_Xiao_chun/article/details/125767778
溜了,溜了…