⚡借助jsQR简简单单在H5中识别图片中的二维码
长按识别图中二维码的业务场景在项目的实际开发中还是蛮常见。但是,一般的业务都集中在微信小程序中。而微信小程序中自带长按识别图中二维码的功能,不需要额外开发。 比如餐厅点完餐,付完款弹出来一个领取奖励商品的海报,长按扫描其中的二维码进入商城小程序的页面领取商品。 但是非微信环境下的长按扫码,然后做一些逻辑怎么做呢? 于是有了调研各种场景下的长按图片识别图中二维码的功能的想法,然后开始不断的翻笔记,搜资料。
写完之后,感觉还是美好的,学到东西了,略微打通了一些经脉。
正文开始
先看效果
如何实现
使用 npm 安装 jsQR
npm install jsqr --save
vue项目中使用方法
<template>
<div class="image-preview">
<!--222.png 是一张二维码图片-->
<img class="img" ref="image" src="../../static/222.png" />
</div>
</template>
<script>
/* eslint-disable */
import jsQR from 'jsqr'
export default {
name: "qrcode",
data() {
return {
url: "",
};
},
mounted(){
const image = this.$refs.image
console.log(image,image.width)
const canvas = document.createElement('canvas')
// 要保证宽高可以完全包裹住图片的宽高(踩过坑)
canvas.width = 300
canvas.height = 300
const ctx = canvas.getContext('2d')
// 将图片画到 canvas 上
ctx.drawImage(image, 0, 0, image.width, image.height)
// 从 canvas 中提取像素数据
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
console.log(canvas.width, canvas.height)
// 将像素数据作为输入,使用 jsQR 库进行解码
const code = jsQR(imageData.data, imageData.width, imageData.height)
// code 就是解码后的数据
console.log('解码结果:', code)
},
methods: {
},
};
</script>
<style>
.img{
width: 300px;
height: 100%;
}
</style>
坑点提前帮你罗列好了,如下
- 二维码需为黑白的,不然code 打印结果为 null
- jsQR函数的第一个参数经测试需要用canvas.getImageData才能转为标准格式(Uint8ClampedArray 数组)
- canvas的宽高要注意,必须包裹住image,展示完整的二维码内容,不然code 打印结果为 null
好了,完结
当然不可能这么快完结啦,下面是我一些延伸的知识点,一起放出来吧,感兴趣的小伙伴可以继续往下看
jsQR扫描已有的图片,还需要调起摄像头吗
不需要
用 jsQR 识别已有的图片不需要调起摄像头,而是可以在后台自行读取图片进行解码,因此在使用过程中不需要用户授权访问摄像头。
jsQR还有哪些其他应用场景呢
- 点击H5页面中某个按钮,弹出一个二维码扫描框,然后你拿着手机对着某某某二维码进行扫描
- 截取视频流中带有二维码的页面,并解析出二维码的内容
我如果要扫描条形码,可以用jsQR吗
- 推荐用QuaggaJS,github上4.8K的星星,值得信赖。顺便说一嘴,QuaggaJS我之前以为它也支持扫描二维码,直到我翻遍文档也没找到类'qrcode_reader'的字眼~~,我认为他不支持扫描二维码
img标签的onload事件执行时会自动解析图片里的二维码吗
不会,虽然我希望他会。 img.onload = function() {} 只是图片加载完成后的回调
Android 和 iOS APP中怎么实现长按图片识别图中的二维码呢
古人说要用自己擅长的,我没怎么写过原生APP(据说可以用ZXing配合原生手势实现) 所以用uniapp/RN转成APP,此处使用uniapp(因为我RN装个环境装半天,所以不用了~~) 代码和思路参考下文 '最终目的是为了扫码后跳到其他H5' 处的总结
长按识别图片二维码的各种应用场景以及解决方案
最终目的是为了扫码后跳到微信小程序,大致可分为两类 一是微信环境内的场景,这种也是最常见的
- 原生微信小程序 / uniapp转的微信小程序中,可以直接通过image标签的show-menu-by-longpress来实现
- 微信环境内的H5 (包括微信小程序内的webview嵌的h5) 可以通过@longtap原生事件模拟长按 + 插件(jsQR)识别到小程序的信息 + 开发一个底部弹窗,展示小程序信息并通过wx-open-launch-weapp点击跳转到指定小程序。 配置是在微信 - 公众号平台
- 提示截图保存,然后在微信扫一扫中打开,哈哈~~ 这是最简单粗暴的,也最不存在兼容问题
- 在微信环境外的网页,短信,邮件通过URL Scheme在h5页面(兼容安卓)中转后通过后端返回的'weixin://dl/business/?t=xxxxxx'跳到小程序(和长按识别图片二维码的功能无关了,除非你非要扯上关系)附上官网地址: developers.weixin.qq.com/miniprogram…
- 原生APP 中跳转至微信某一小程序的指定页面,完成服务后再跳回至原 APP 配置是在微信 - 开放平台
- 开发者在微信开放平台帐号下申请移动应用并通过审核后,即可获得移动应用拉起小程序功能权限
- 开发前需下载Android开发工具包(SDK)
- 调用接口:WXLaunchMiniProgram 移动应用跳转到小程序
- 官网地址(安卓案例):developers.weixin.qq.com/doc/oplatfo…
- uniapp转的APP:通过uniapp集成的HTML5 Plus里的launchMiniProgram 来打开微信小程序,代码简单,如下,但是配置要配置一大堆配置是在微信 - 开放平台
// 跳转微信小程序
// response 后台给的参数
onWeinxinApp(response) {
//#ifdef APP-PLUS
plus.share.getServices(function(res) {
var sweixin = null;
for (var i = 0; i < res.length; i++) {
var t = res[i];
if (t.id == 'weixin') {
sweixin = t;
}
}
if (sweixin) {
sweixin.launchMiniProgram({
id: response.g_id, //这里写你的小程序原始id(以gh开头)
type: 0, //这里是不同的环境(默认0)
path: response.path //这里是指定页的路径,如需传参直接字符串拼接(首页可以省略)
});
this.queryPayResult();
}
}, function(res) {
console.log(JSON.stringify(res));
});
//#endif
最终目的是为了扫码后跳到其他H5 其实上文有提到,此处总结一下
- @longtap原生事件模拟长按(不同的开发环境有对应的或相似的事件)
- 插件(jsQR)识别到二维码的信息(参考文章开篇vue中使用jsQR)
- 开发一个底部弹窗,展示二维码信息(可省略)
- 通过二维码的信息中的其他H5页面信息,跳转到其他H5页面
完结
这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。 欢迎转载,但请注明来源。 最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。
转载自:https://juejin.cn/post/7218506966545186877