浏览器调取摄像头拍照并有遮罩层

近来在写一个公众号的项目,因为开发需求,需要调取手机摄像头拍照。最重要的是要有遮罩层,这就限制了不能调用手机自带的摄像头。

项目框架是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

溜了,溜了

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值