H5端扫码识别二维码 VUE(开箱即用)

公司有这个需要本来想CV,找了很久没找到,都是些残文和AI文章。就干脆自己写了一个。

CV就能用,开箱即用兄弟们,觉得好用的点个赞吧兄弟们。

目前只做了移动端的适配哦,用电脑打开是打不开的做了强制限制的。

不罗嗦,上代码

需要安装JSQR去解析二维码

控制台命令: npm install jsqr --save

<template>
  <div>
    <div v-if="xsyc">
        <div ref="videocontainer" v-if="xsycerweima">
      <div class="video-container">
        <!--video用于显示媒体设备的视频流,自动播放 autoplay-->
        <video id="video" autoplay  playsinline webkit-playsinline  ref="video" ></video>
        <!--描绘video截图-->
        <canvas id="canvas" style="width: 100%;height: 100%;" v-show="videofalse"></canvas>
         <!-- 遮罩层 -->
        <div class="wrap" ref="wrap">
          <!-- 扫码线 -->
               <!-- 直角线 -->
            <i class="iconfont icnfontzhijiao1" >&#xe603;</i>
            <i class="iconfont icnfontzhijiao2">&#xe601;</i>
            <i class="iconfont icnfontzhijiao3">&#xe604;</i>
            <i class="iconfont icnfontzhijiao4">&#xe602;</i>
          <div class="saomasan">
        </div>
        </div>
        <div ref="shengyupx"  class="shengyupx">
          <div class="dibubuju">
            <i class="iconfont">&#xe600;</i>
          <div>
            扫描二维码
          </div>
          </div>
        </div>
    </div>
        </div>
        <div v-else>
         识别到你的二维码信息是: {{ codedata }}
        </div>
      </div>
    <div v-else>
        <div class="PCduan">
            扫描二维码暂不支持电脑端,请移步到手机端。
        </div>
    </div>
  </div>
  </template>
<script>
import jsQR from 'jsqr'
export default {
  name: 'LoginIndex',
  data () {
    return {
      videofales: false,
      video: null,
      canvas: null,
      ctx: null,
      xsyc: true,
      xsycerweima: true,
      codedata: '',
      intervalId: null
    }
  },
  components: {

  },
  created () {
    const system = {}
    system.pingtai = /(Win32|Win16|WinCE|Mac68K|MacIntel|MacIntel|MacPPC|Linux mips64)/i.test(navigator.platform)
    if (system.pingtai) {
      // 电脑
      console.log('电脑')
      this.xsyc = false
    } else {
      // 手机
      console.log('手机')
      this.xsyc = true
    }
  },
  mounted () {
    // 获取DOM元素
    if (this.xsyc) {
      this.video = document.getElementById('video')
      this.canvas = document.getElementById('canvas')
      this.canvas.width = window.innerWidth
      this.canvas.height = window.innerHeight
      this.ctx = this.canvas.getContext('2d')
      console.log(window)
      this.scan()
      this.intervalId = setInterval(() => {
        this.capture()
      }, 100)
    }
  },
  methods: {
    // 兼容浏览器获取用户媒体方法
    // constrains 参数用于指定要使用的摄像头和音频设备。success 和 error 参数用于处理成功和失败的情况。
    getUserMedia (constrains, success, error) {
      if (navigator.mediaDevices.getUserMedia) {
        // 最新标准API

        navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error)
      } else if (navigator.webkitGetUserMedia) {
        // webkit内核浏览器
        navigator.webkitGetUserMedia(constrains).then(success).catch(error)
      } else if (navigator.mozGetUserMedia) {
        // Firefox浏览器
        navigator.mozGetUserMedia(constrains).then(success).catch(error)
      } else if (navigator.getUserMedia) {
        // 旧版API
        navigator.getUserMedia(constrains).then(success).catch(error)
      }
    },
    success (stream) {
      // 将一个视频流(stream)转换为一个可以被视频元素加载的URL,然后将这个URL设置为视频元素的源。这样,浏览器就可以自动播放这个视频流了。
      // 兼容webkit核心浏览器
      // 将视频流设置为video元素的源
      this.video.srcObject = stream
      this.video.play()
    },
    error (error) {
      console.log('访问用户媒体设备失败:' + error.name + ' ' + error.message)
    },
    // 调用摄像头
    scan () {
      if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
        // 调用用户媒体设备,访问摄像头
        this.getUserMedia({
          audio: false,
          video: {
            facingMode: 'environment', // user 前置摄像头 environment 后置摄像头
            width: { ideal: 1280 },
            height: { ideal: 720 },
            frameRate: { ideal: 30 },
            codec: 'video/mp4;codecs="avc1.42E01E"'
          }
        }, this.success, this.error)
      } else {
        alert('你的浏览器不支持访问用户媒体设备')
      }
    },
    // 循环这个动作就可以实现扫码的效果
    capture () {
      const videoWidth = window.innerWidth
      const videoHeight = window.innerHeight
      this.ctx.drawImage(this.video, 0, 0, videoWidth, videoHeight)

      // 截取高亮部位图片
      const cavaswidth = this.canvas.width
      const cavasheight = this.canvas.height
      const centerX = cavaswidth / 2
      const centerY = cavasheight / 2
      // 这里是扫描区域的控制 和  this.$refs.wrap.offsetWidth的大小一样 调整wrap的宽度可以调整扫描区域
      const desiredSquareSize = this.$refs.wrap.offsetWidth
      const squareSize = desiredSquareSize
      const x = centerX - squareSize / 2
      const y = centerY - squareSize / 2
      // 需要识别的二维码部分给jsQR去解析
      const imageData = this.ctx.getImageData(x, y, squareSize, squareSize)
      const code = jsQR(imageData.data, squareSize, squareSize)
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      if (code) {
        console.log('找到二维码', code.data)
        this.codedata = code.data
        this.xsycerweima = false
        clearInterval(this.intervalId)
        this.video.stop()
      } else {
        console.log('未找到二维码')
      }
    }
  }
}
</script>
<style  scoped>
  @font-face {
    font-family: 'iconfont';  /* Project id 4504064 */
    src: url('//at.alicdn.com/t/c/font_4504064_wfyvfsvop7d.woff2?t=1712828573992') format('woff2'),
         url('//at.alicdn.com/t/c/font_4504064_wfyvfsvop7d.woff?t=1712828573992') format('woff'),
         url('//at.alicdn.com/t/c/font_4504064_wfyvfsvop7d.ttf?t=1712828573992') format('truetype');
  }
  .iconfont{
      font-family:"iconfont" !important;
      font-size:25px;font-style:normal;
      -webkit-font-smoothing: antialiased;
      -webkit-text-stroke-width: 0.2px;
      -moz-osx-font-smoothing: grayscale;
    }
  *{
    margin:0px; padding:0px;
    overflow: hidden;
  }
  .video-container {
    /* width: 100vw;
    height: 100vh; */
    overflow: hidden;
  }
  #video {
    /* object-fit: cover; */
    /* object-position: center center; */
    /* object-position: ; */
    /* height: 100%; */
    width: 100%;
    object-fit: contain;
    position: absolute;
    overflow: hidden;
  }
  #canvas {
  width: 100vw;
  height: 100vh;
  }
  #capture {
    content:'';
    position: absolute;
    top: 0;
    right: 0;
  }
  .wrap {
    content:'';
    position: absolute;
    width: 70vw;
    height: 70vw;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%); /*默认居中*/
    box-shadow: 0 0 0 999vw rgba(0, 0, 0, .8); /*足够大的投影*/
  }
  .shengyupx {
    position: absolute;
    background-color:rgba(44, 40, 40, 1);
    bottom: -1vh;
    height: 10vh;
    width: 100%;
    z-index: 999;
    overflow: hidden;

  }
  .dibubuju {
   display: flex;
   flex-direction: column;
   justify-content: center;
   align-items: center;
   color: #007bff;
   font-size: 2vw;
  }
  .icnfontzhijiao1 {
    content:'';
    position: absolute;
    left: 0.4vw;
    top: -0.4vh;
    color: #007bff;
  }
  .icnfontzhijiao2 {
    content:'';
    position: absolute;
    right: 0.4vw;
    top: -0.4vh;
    color: #007bff;
  }
  .icnfontzhijiao3 {
    content:'';
    position: absolute;
    left: 0.4vw;
    bottom: -0.7vh;
    color: #007bff;
  }
  .icnfontzhijiao4 {
    content:'';
    position: absolute;
    right:  0.4vw;
    bottom: -0.7vh;
    color: #007bff;
  }
  .saomasan {
    content:'';
    position: absolute;
    left: 50%;
    top: 0%;
    transform: translate(-50%,-50%); /*默认居中*/
    height: 3px;
    width: 300px;
    background: -webkit-linear-gradient(left,rgba(255, 255, 255, 0),#007bff,rgba(255,255,255,0));
    background: linear-gradient(to right, rgba(255, 255, 255, 0),#007bff,rgba(255,255,255,0));
    animation: moveLine 3s linear infinite;
  }
  @keyframes moveLine {
    0% { transform: translate(-50%,-50%) translateY(-300%); }
    50% { transform: translate(-50%,-50%) translateY(10000%); }
    100% { transform: translate(-50%,-50%) translateY(-100%); }
  }

  .PCduan {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    font-size: 4vw;
  }
  </style>

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码
Vue H5中,如果要在安卓系统上识别二维码,可以使用第三方库进行实现。其中比较常用的库有两个,分别是QuaggaJS和zxing。下面分别对这两个库进行简单介绍: 1. QuaggaJS QuaggaJS是一个用于条形码和二维码扫描的JavaScript库,可以实现跨平台的条形码和二维码扫描功能。具体使用可以按照以下步骤进行: 1)使用npm安装quagga库:npm install quagga 2)引入quagga: import Quagga from 'quagga'; 3)在mounted生命周期钩子函数中初始化Quagga: mounted() { Quagga.init({ inputStream : { name : "Live", type : "LiveStream", target: document.querySelector('#yourElement') }, decoder : { readers : ['ean_reader', 'ean_8_reader'] } }, function(err) { if (err) { console.log(err); return; } Quagga.start(); }); } 4)在使用时,可以在页面中设置一个元素,通过查询选择器获取到该元素,将其传入到配置中,就可以在该元素上展示识别到的二维码信息。 2. zxing zxing是一款开源的条形码和二维码识别库,使用简单,但是较QuaggaJS略显复杂,需要按以下步骤进行设置: 1)使用npm安装zxing库:npm install zxing 2)引入zxing: import zxing from 'zxing'; 3)新建一个单例的扫描器对象: const scanner = new zxing.BrowserQRCodeReader(); 4)在使用时,可以通过调用扫描器对象的方法,获取到扫描后的结果。具体使用可以参考下面的代码样例: startScan() { scanner.getVideoInputDevices() .then((video) => { console.log("videoInputDevices", video); return scanner.decodeFromVideoDevice(video[0].deviceId, 'video'); }) .then((result) => { console.log(result); }) .catch((err) => { console.error(err); }) } 综上所述,以上是在Vue H5中实现安卓系统二维码识别的两种方案,开发者可以根据自己的实际需求来选择其中的一种进行使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值