vue识别二维码

709 阅读1分钟
/**
*@Author: 周贞荣
*@Date 2021/8/23 19:39
*@Description vue识别二维码
*@File ZzrQrcode.vue 文件名称
*@Modify 周贞荣
*/
<template>
    <div class="zzrQrcode">
        <video id="videoDom" autoplay="autoplay"></video>
        <canvas id="qrcanvas" style="display: none;"></canvas>
        <img id="qrcanvasImg" style="display: none;">
    </div>
</template>

<script>
    import jsQR from './lab/jsQR';

    export default {
        name: "ZzrQrcode",
        data() {
            return {
                // 视频播放节点
                videoDom: null,
                // 视频标签外部节点
                codeDom: null,
                // 循环记录时间对象
                term: null
            }
        },
        methods: {
            /**
             * 获取二维码地址
             * @param {Object} url 二维码携带的地址信息
             */
            uploadCode(url) {
                this.term && window.clearInterval(this.term);
                this.$emit('success', url);
            },
            /**
             * 截图并获取二维码
             */
            base64ToqR() {
                // 截图存储画布
                const canvas = document.getElementById("qrcanvas");
                // 设置画布宽为视频的宽
                canvas.width = this.videoDom.clientWidth;
                // 设置画布高为视频的高
                canvas.height = this.videoDom.clientHeight;
                // 创建图片存储地址
                const img = new Image();
                // 设置画布高为视频的高
                img.height = this.videoDom.clientHeight;
                // 设置图片宽为视频的宽
                img.width = this.videoDom.clientWidth;
                const ctx = canvas.getContext("2d");
                ctx.drawImage(this.videoDom, 0, 0);
                img.src = canvas.toDataURL('image/webp');
                const imageData = ctx.getImageData(0, 0, img.width, img.height);
                img.onload = () => {
                    // 图片转二维码信息
                    const code = jsQR(imageData.data, imageData.width, imageData.height, {
                        inversionAttempts: "dontInvert",
                    });
                    // 存在二维码信息调用二维码推送
                    code && this.uploadCode(code)
                };
            },
            /**
             * 获取视频流
             * @param stream 视频流地址
             * */
            playAudioToUser(stream) {
                if ('srcObject' in this.videoDom) {
                    this.videoDom.srcObject = stream;
                    this.term = window.setInterval(this.base64ToqR, 1000);
                } else {
                    this.videoDom.src = URL.createObjectURL(stream);
                }
            },
            /**
             * 视频流获取失败
             * */
            playAudioToUserError(e) {
            this.term && window.clearInterval(this.term);
                this.$emit('fail', e)
            }
        },
        /**
         * 组件加载渲染完成执行回调方法
         */
        mounted() {
            this.videoDom = document.getElementById('videoDom');
            /**
             * 基础资源加载完成
             */
            navigator.getUserMedia({
                video: {
                    facingMode: 'environment'
                },
                audio: false,
            }, this.playAudioToUser, this.playAudioToUserError);
        },
        beforeDestroy(){
        this.term && window.clearInterval(this.term);
        }
    }
</script>

<style scoped lang="scss">
    .zzrQrcode {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: #000;
        z-index: 888;
        video{
            width: 100%;
            height: 100%;
        }
    }
</style>

使用方式

<ZzrQrcode @success="" @fail="" v-if=''/>