vue调用摄像头拍照

vue中调用本地摄像头拍照生成base64的图像

复制可以直接使用

<template>
    <div class="main">
        <el-card>
            <div slot="header">
                <div>
                    <span>拍照</span>
                    <i @click="drawImage(true)" class="el-icon-refresh"></i>
                </div>
            </div>
            <div>
                <div class="camera_outer" ref="imgbg">
                    <div>
                        <video
                            style="display: none"
                            id="videoCamera"
                            :width="videoWidth"
                            :height="videoHeight"
                            muted
                            autoplay
                        ></video>
                        <canvas
                            style="display: none"
                            id="canvasCamera"
                            :width="videoWidth"
                            :height="videoHeight"
                        ></canvas>
                    </div>
                    <div v-if="imgSrc" class="img_bg_camera">
                        <img :src="imgSrc" alt class="tx_img" />
                    </div>
                </div>
            </div>
        </el-card>
    </div>
</template>

<script>
export default {
    components: {},
    data() {
        return {
            /** 照相机弹窗模块-start */
            imgSrc: undefined,
            thisVideo: null,
            thisContext: null,
            thisCancas: null,
            videoWidth: 250,
            videoHeight: 130,
            takePhotos: true, // 控制警告弹窗
            /** 照相机弹窗模块-end */
        };
    },

    mounted() {
        this.init();
    },
    beforeDestroy() {
        this.stopNavigator();
    },
    methods: {
        init() {
            this.getCompetence();
        },
        // 调用摄像头权限
        getCompetence() {
            //必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点
            this.$nextTick(() => {
                const _this = this;
                this.thisCancas = document.getElementById('canvasCamera'); //这里是需要截取的canvas的Id名称
                this.thisContext = this.thisCancas.getContext('2d');
                this.thisVideo = document.getElementById('videoCamera');
                // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
                if (navigator.mediaDevices === undefined) {
                    navigator.menavigatordiaDevices = {};
                }
                // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
                // 使用getUserMedia,因为它会覆盖现有的属性。
                // 这里,如果缺少getUserMedia属性,就添加它。
                if (navigator.mediaDevices.getUserMedia === undefined) {
                    navigator.mediaDevices.getUserMedia = function (
                        constraints
                    ) {
                        // 首先获取现存的getUserMedia(如果存在)
                        let getUserMedia =
                            navigator.webkitGetUserMedia ||
                            navigator.mozGetUserMedia ||
                            navigator.getUserMedia;
                        // 有些浏览器不支持,会返回错误信息
                        // 保持接口一致
                        if (!getUserMedia) {
                            return Promise.reject(
                                new Error(
                                    'getUserMedia is not implemented in this browser'
                                )
                            );
                        }
                        // 否则,使用Promise将调用包装到旧的navigator.getUserMedia
                        return new Promise(function (resolve, reject) {
                            getUserMedia.call(
                                navigator,
                                constraints,
                                resolve,
                                reject
                            );
                        });
                    };
                }
                const constraints = {
                    audio: false,
                    video: {
                        width: _this.videoWidth,
                        height: _this.videoHeight,
                        transform: 'scaleX(-1)',
                    },
                };
                navigator.mediaDevices
                    .getUserMedia(constraints)
                    .then(function (stream) {
                        // 旧的浏览器可能没有srcObject
                        if ('srcObject' in _this.thisVideo) {
                            _this.thisVideo.srcObject = stream;
                        } else {
                            // 避免在新的浏览器中使用它,因为它正在被弃用。
                            _this.thisVideo.src =
                                window.URL.createObjectURL(stream);
                        }
                        _this.thisVideo.onloadedmetadata = function () {
                            _this.thisVideo.play();
                        };
                        _this.takePhotos = true;
                    })
                    .catch(err => {
                        _this.takePhotos = false;
                        console.log(err);
                    });
            });
        },
        //绘制图片
        drawImage() {
            if (!this.takePhotos) {
                this.imgSrc = '';
                this.$message.error($t('未检测到摄像设备,或未打开权限'));
                return;
            }
            // 点击,canvas画图
            this.thisContext.drawImage(
                this.thisVideo,
                0,
                0,
                this.videoWidth,
                this.videoHeight
            );
            // 获取图片base64链接,展示到界面中的也是这个url地址
            this.imgSrc = this.thisCancas.toDataURL('image/png');
        },
        //清除
        stopNavigator() {
            if (this.thisVideo && this.thisVideo !== null) {
                this.thisVideo = null;
                this.imgSrc = '';
            }
        },
    },
    computed: {},
};
</script>
<style lang="scss" scoped>
.camera_outer {
    width: 100%;
    height: 130px;
    .img_bg_camera {
        height: 130px;
        img {
            width: 100%;
            height: 100%;
        }
    }
}
</style>


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值