手机移动端 您所在的位置:网站首页 如何查找手机二维码信息 手机移动端

手机移动端

2024-06-28 09:04| 来源: 网络整理| 查看: 265

一、场景

手机移动端-原生js 浏览器h5 解决 识别二维码 条形码功能;

不借助Hbuilder.需要自己打包成APP,比如用Hbuilder打包,浏览器端项目h5 无打包成app部署 X 不采用

不借助微信扫一扫,调用微信js-jdk有多麻烦,还要认证服务号,也不适用 其它浏览器打开 X 不采用

二、思路 1.思路一:input(相机拍照)+ 条形码或二维码识别js支持库

通过h5-input[camera] 调用相机进行拍照成图片,通过条形码等识别库 解析出 数据;

1-1.方案一:input+ Quagga识别库,success, 可识别 条形码,不能识别二维码;

quagga库地址 https://www.npmjs.com/package/quagga

npm install quagga --save 1-2.方案二:input+jsqr识别库,success,可识别条形码,也可识别二维码,但二维码识别很局限性,如果只做条形码识别可采用,若是识别二维码不适用;

jsqr库地址 https://www.npmjs.com/package/jsqr

npm install jsqr --save

例: 1.正方形不带其它无效内容 只二维码的图片,设置jsqr识别长宽 100*100 ,可成功识别

       2.长方形带其它无效内容,比如拍照出来的二维码图片,设置jsqr识别长宽 自适(传入图片的长宽 或100*100),都识别失败

1-3.方案三: input+qrcode库, 失败 qrcode.decode(img) 2.思路二:调用摄像头(video动态识别)+ 条形码或二维码识别js支持库

调用手机原生摄像头 动态识别 用相关支持js库  解析 二维码 条形码

2-1.方案四:video+ zxing识别库,success,可识别 条形码 可识别二维码,完美解决,楼主采用的这种;

 zxing-js/library库地址 https://github.com/zxing-js/library

npm install @zxing/library --save 三、实例 1-1.方案一

vue-demo

车架号 .input-cells{ display: flex; justify-content:space-between; align-items: center; position: relative; background-color: #fff; overflow: hidden; padding: .06rem .15rem; height: .32rem; line-height: .32rem; font-size: .14rem; } .input-label{ margin-left: 0; font-size: .14rem; width: .9rem; } .input-cells>input{ font-size: .14rem; text-align: right; } .input-cells>img{ width: .06rem; height: .1rem; margin-right: .03rem; } .qr-item{ width: .3rem; height: 100%; background-size: 120%; position: relative; overflow: hidden; border: 1px solid #dae7f6; background-color: #f5f5f5; } .qr-item-input{ opacity: 0; width: 100%; height: 100%; background-size: 100%; position: absolute; top: 0; left: 0; } /*common*/ .flex{ display: flex; } .a-center{ align-items: center; } .f-fl{ float: left; } .ml5{ margin-left: .05rem; } .mr10{ margin-right: .1rem; }  

es6引入使用 

import Quagga from 'quagga'

使用

import Quagga from 'quagga' export default { name: '', data() { return { queryParams: { vin: null }, isUploadBarCode: true, // 控制销毁 } }, mounted() { }, methods: { // 图片 识别 条形码 toQR(e) { const that = this const file0 = e.target.files[0] // console.log('toQR()-file0', file0) this.isUploadBarCode = false Quagga.decodeSingle({ inputStream: { name : 'image', type : 'ImageStream', // size: 1600, // 这里指定图片的大小,需要自己测试一下 singleChannel: false, }, locator: { patchSize: 'medium', halfSample: false }, numOfWorkers: 1, decoder: { // ean_reader 这里指定ean条形码,就是国际13位的条形码 code39 code_128 readers: ['code_128_reader'] }, // readers: ['code_128_reader'], locate: true, src: URL.createObjectURL(file0) },(result) => { console.log('Quagga()-result', result) // let code = result.codeResult.code if (result && result.codeResult) { that.queryParams.vin = result.codeResult.code // 执行 页面请求刷新 } else { that.queryParams.vin = null console.warn('识别失败,请手动输入') } this.isUploadBarCode = true }) }, } }   1-2.方案二

方案二 html+css 公用与 方案一  

 qrcodeSearch.js

// import QRCode from '../libs/qr/qrcode' import jsqr from 'jsqr' // 二维码 或 条形码 识别 export function showQrCode(file, params, callback) { const ready = new FileReader() /* 开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/ ready.readAsDataURL(file) // 调用reader.readAsDataURL()方法,把图片转成base64 ready.onload = function() { const re = this.result canvasDataURL(re, params, callback) } } function canvasDataURL(path, obj, callback) { const img = new Image() img.src = path // 生成canvas const canvas = document.createElement('canvas') // const canvas = document.getElementById('qrcanvas') const ctx = canvas.getContext('2d') // const _this = this img.onload = function() { console.log('canvasDataURL()-img', img.height, img.width) // let w = img.width // let h = img.height const w = 100 const h = 100 ctx.clearRect(0, 0, w, h) ctx.drawImage(img, 0, 0, w, h); const imageData = ctx.getImageData(0, 0, w, h); const code = jsqr(imageData.data, w, h); const res = { data: null, message: '识别成功', code: 0, } if(code){ res.data = code.data callback(res) }else{ res.code = -1 res.data = null res.message = '识别失败' callback(res) } } }

使用

import * as QrCode from './qrcodeSearch' export default { name: '', data() { return { queryParams: { vin: null }, isUploadBarCode: true, // 控制销毁 } }, mounted() { }, methods: { // 图片 识别 条形码 toQR(e) { const that = this const file0 = e.target.files[0] // console.log('toQR()-file0', file0) this.isUploadBarCode = false QrCode.showQrCode(file0, {}, function (res) { this.isUploadBarCode = true console.log('showQrCode()-res', res) if (res.code === 0) { that.queryParams.vin = res.data } else { console.warn('识别失败,请手动输入') } }) }, } } 2-1.方案四

  注意,因为调用原生摄像头 要在 https环境下,故需要把代码发布到 带域名(https)的测试环境 进行调试【这是必要的前提条件,没有测试环境就不要整了】。故而代码调整要反复发布构建代码,不过楼主的这个例子已经是整好了的;

vue-demo

{{tipMsg}} /*vjs-fluid 自适video 长宽*/ .video{ /*border: 1px solid gray;*/ margin-top: .5rem; /*width: 2.6rem;*/ /*height: 3rem;*/ } .tip{ color: white; font-size: .16rem; } /* common */ .bgc-f4f4f4{ background-color: #363636; } .page{ overflow-y: auto; position: relative; }

使用

import { MessageBox } from 'mint-ui' import { BrowserMultiFormatReader } from '@zxing/library' export default { name: 'qr-code-search', components: {}, data() { return { loadingShow: false, codeReader: new BrowserMultiFormatReader(), textContent: null, vin: null, tipMsg: '正在尝试识别....', tipShow: false } }, created() { // this.tipShow = true this.openScan() }, methods: { async openScan() { const that = this that.codeReader.getVideoInputDevices().then((videoInputDevices) => { that.tipShow = true that.tipMsg = '正在调用后置摄像头...' console.log('videoInputDevices', videoInputDevices); // 默认获取第一个摄像头设备id let firstDeviceId = videoInputDevices[0].deviceId; // 获取第一个摄像头设备的名称 const videoInputDeviceslablestr = JSON.stringify(videoInputDevices[0].label); if (videoInputDevices.length > 1) { // 判断是否后置摄像头 if (videoInputDeviceslablestr.indexOf('back') > -1) { firstDeviceId = videoInputDevices[0].deviceId; } else { firstDeviceId = videoInputDevices[1].deviceId; } } that.decodeFromInputVideoFunc(firstDeviceId) }).catch((err) => { that.tipShow = false console.error(err); }); }, async openScanTwo() { const that = this // codeReader.reset() // 重置 // that.textContent = null // 重置 that.codeReader = await new BrowserMultiFormatReader() that.codeReader.getVideoInputDevices().then((videoInputDevices) => { that.tipShow = true that.tipMsg = '正在调用后置摄像头...' console.log('videoInputDevices', videoInputDevices); // 默认获取第一个摄像头设备id let firstDeviceId = videoInputDevices[0].deviceId; // 获取第一个摄像头设备的名称 const videoInputDeviceslablestr = JSON.stringify(videoInputDevices[0].label); if (videoInputDevices.length > 1) { // 判断是否后置摄像头 if (videoInputDeviceslablestr.indexOf('back') > -1) { firstDeviceId = videoInputDevices[0].deviceId; } else { firstDeviceId = videoInputDevices[1].deviceId; } } that.decodeFromInputVideoFunc(firstDeviceId) }).catch((err) => { that.tipShow = false console.error(err); }); }, decodeFromInputVideoFunc(firstDeviceId) { const that = this that.codeReader.reset() // 重置 that.textContent = null // 重置 that.codeReader.decodeFromInputVideoDeviceContinuously(firstDeviceId, 'video', (result, err) => { that.tipMsg = '正在尝试识别...' // let nowContent = null that.textContent = null if (result) { console.log(result); that.textContent = result.text; if (that.textContent) { that.tipShow = false that.msgBoxFunc(that.textContent) } } if (err && !(err)) { that.tipMsg = '识别失败' setTimeout(() => { that.tipShow = false },2000) console.error(err); } }); }, // that.$createDialog 是 cube-ui滴滴 messageBox ,到这一步 二维码值已出,这里是可有可无的代码块,看各自项目ui使用情况 自行替换 messageBox msgBoxFunc(textContent) { const that = this // alert('8执行了 msgBoxFunc(),textContent:' + textContent) // cube-ui messageBox that.$createDialog({ type: 'prompt', // icon: 'cubeic-alert', title: '识别内容', // content: that.textContent, prompt: { value: textContent, placeholder: '请输入' }, confirmBtn: { text: '确定内容', active: true, disabled: false, href: 'javascript:;' }, cancelBtn: { text: '继续识别', active: false, disabled: false, href: 'javascript:;' }, onConfirm: (e, promptValue) => { // that.hide() console.log('onConfirm: ()') that.vin = promptValue }, onCancel: () => { console.log('onCancel: ()') that.$nextTick(()=>{ that.openScanTwo() }) } }).show() }, // msgBoxFunc2() 整块代码是mint-ui messageBox示例用,此处未使用,可直接注释; msgBoxFunc2(textContent) { // mint-ui messageBox 有重复 inputValue值问题,新调用 显示是旧的值 const that = this // alert('8执行了 msgBoxFunc(),textContent:' + textContent) MessageBox.prompt('识别内容', { inputValidator: (val) => { if (val === null) { return true;//初始化的值为null,不做处理的话,刚打开MessageBox就会校验出错,影响用户体验 } }, confirmButtonText: '确定内容', cancelButtonText: '继续识别', inputValue: textContent, }).then(({value, action}) => { if (action === 'confirm') { that.vin = value } if (action === 'cancel') { that.$nextTick(()=>{ that.openScanTwo() }) } }).catch(err => { console.log(err); }) } } } 四、尾结

  道路过程是曲折坎坷的,结果是良好的,以为整不出来的然后柳暗花明;

参考文章:

https://www.jianshu.com/p/30a34157c7d1    zing-js/library

https://blog.csdn.net/aoshilang2249/article/details/105222706   MediaDevices.getUserMedia undefined 的问题

https://blog.csdn.net/yingzhi3104/article/details/105557591 quagga识别条形码图片

https://blog.csdn.net/qq_37705048/article/details/79816438 qrcode.js的识别

https://blog.csdn.net/haiyang5233233/article/details/105874129 调用摄像头是提示 navigator.mediaDevices.getUserMedia

https://blog.csdn.net/weixin_30260399/article/details/96458034 调用后置摄像头问题



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有