⌚️老王

一切从简

  🏠首页   |  📁程序员杂记   |  ⌚关于我

浏览器中用JavaScript识别二维码

浏览器中使用纯JS读取识别二维码内容。可用于上传二维码图时,对二维码内容进行校验,避免上传非法二维码。

基于jsQR(https://github.com/cozmo/jsQR) ,做如下改动:

// 原调用方式需要传入Uint8ClampedArray类型的图片数据,并要知道图片的宽高
const code = jsQR(imageData, width, height, options?);

// 修改后直接传入图片URL、Base64、Blob
jsQR('https://xxx/ooo.jpg').then((success) => {
  console.log(success)
}, () => {
  console.log('error')
})

如果用在jQuery Uploader中,可以实现上传前检查二维码内容,比如:

$('#upload_alipay').fileupload({
  add: function(e, data){
    jsQR(URL.createObjectURL(data.files[0])).then((success) => {
      // 只允许支付宝二维码
      if (!/^https:\/\/qr\.alipay\.com\//.test(success.data)) {
        alert('请上传正确的支付宝收款二维码')
      }else{
        data.submit()
      }
    }, () => {
      alert('请上传正确的支付宝收款二维码')
    })
  }
})

对jsQR的改动如下:

// jsQR 函数名改名为 _jsQR
function _jsQR(data, width, height, providedOptions) {
    ...原jsQR函数体不变...
}

// 重新定义一个jsQR函数
// 用canvas读取并转化图片为Uint8ClampedArray类型
function jsQR(data, providedOptions){
    var width
    var height
    var canvas = document.createElement('canvas')
    var ctx = canvas.getContext('2d')
    var image = new Image()
    // 允许图片地址跨域
    image.crossOrigin = 'anonymous'
    image.src = data
    // 等图片加载完成进行转换
    return new Promise(function (resolve, reject) {
        image.onload = () => {
            width = image.width
            height = image.height
            canvas.width = width
            canvas.height = height
            ctx.drawImage(image, 0, 0, width, height)
            // 图片转成Uint8ClampedArray
            var imageData = ctx.getImageData(0, 0, width, height)
            // 调用原jsQR方法
            var result = _jsQR(imageData.data, width, height, providedOptions)
            if(result){
                resolve(result)
            }else{
                reject()
            }
        }
    })
}
jsQR.default = jsQR;
exports.default = jsQR;
Tags: