微信二维码长按无法识别问题解析

近来在写H5页面时发现在手机端微信里长按识别二维码有时会出现不能识别的bug,最近就对这些可能导致二维码不能识别的bug做了一下研究,写出来,和大家分享一下。

   

一、微信识别二维码的原理机制

   我们先来看一下微信识别二维码的原理机制:

   “微信识别二维码采用的逻辑是截屏识别,当客户端发现用户在网页的img标签内进行长按操作时,会立刻截屏并且启动二维码识别算法。所以这里用于二维码识别的图片是截屏,而不是之前有人提到的img标签中的图片。

   为什么要用截屏,这也是一个开发时候的思考。客户端截屏时候,可以不用考虑网络传输等因素,最快的得到识别结果,否则就需要走一次图片下载的逻辑,用户长按后等待的时间会加长,体验上也失去了快感。当然,这也带来了识别不出的问题(所以正在考虑先截屏,截屏识别失败再下载的新逻辑)。”

   详情请参考:网页中二维码识别规则

 

二、二维码识别常见的BUG及解决方法

1、二维码图片直接放在background里时无法识别

   由上述二维码识别原理我们可以知道客户端是检测网页的img标签内进行长按操作时,会立刻截屏并且启动二维码识别算法。所以当将二维码图片直接放在background中时,识别效果特别差,基本上是识别不出来的。所以最好是将二维码图片单独切出来放在了img标签中。

 

2、多张二维码图片无法在同一屏幕中共享

   微信识别二维码的原理是长按的时候相当于将当前手机屏幕截屏,识别截屏后的图片,这样一张图片有两个二维码图的时候当然只会识别出一个。建议解决办法是不要在同一屏幕中放多张图片或者提示用户双击放大二维码进行二维码识别。

 

3、多次执行长按二维码的功能会导致内存泄漏,手机会变卡

   多次执行长按二维码的功能会导致手机(iPhone)变卡。长按识别二维码,多次测试后右键识别出来是二维码图片(即没有出现“识别二维码”的按钮)。

 

4、iOS 版微信长按识别二维码无法正常识别

(8.21 更新:最新版6.2.4 已经修复该bug)

   以下实测在iOS 版(iPhone)微信6.2.2 中有此bug,安卓版微信暂时没有发现有此bug。

   对于二维码区域,实际可识别区域是整体上移64px,64px的偏移与二维码大小本身无关。下面的红色的区域即为实际可识别的二维码区域。为什么是神秘的64px?因为64px正好是微信内置浏览器标题栏+系统标题栏的高度。可以认为微信客户端在识别二维码的时候忽略了微信标题栏+系统状态栏的高度。

解决方案有两个

(1)通过为img增加padding增大可接触面积。

(2)为二维码本身增加透明底部背景,如下:

 

5、IOS系统meta缩放问题导致二维码无法识别

   在安卓版的微信长按二维码可以识别(前提是你的微信版本到支持此功能),但是到了苹果版的微信就识别不了,这时候可能是缩放的问题:

(1)设置了初始缩放设置为1,最大缩放值要>=1,不支持缩放。--->可以识别。

   如<meta content="width=device-width, initial-scale=1, maximum-scale=1.2, user-scalable=0" name="viewport" />

(2)设置了初始缩放设置为小于1或者大于1,最大缩放值大于或者等于初始缩放,不支持缩放。--->不可以识别。

   如<meta content="width=device-width, initial-scale=1.1, maximum-scale=1.2, user-scalable=0" name="viewport" />

(3)设置了初始缩放设置为1,最大缩放值要>=1,支持缩放。--->页面不缩放之前可以识别,一旦页面缩放过后就不可以识别。

   如<meta content="width=device-width, initial-scale=1, maximum-scale=1.2, user-scalable=1" name="viewport" />

(4)都不设置时,不可以识别。

(5)设置了固定的宽,导致二维码的实际位置偏移到屏幕外

   <meta content="width=750, initial-scale=1, maximum-scale=1.2, user-scalable=0" name="viewport" />

(6)页面有css样式fixed --->不可以识别。

 

以上这些设置导致二维码图片定位不准,或者二维码全部跑到屏幕外或者部分跑到屏幕外而无法识别。以下是其解决办法:

方法1
   设置:初始缩放为1,最大缩放值要大于1,不支持缩放。如下:

   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no"/>

 

方法2

   首先要把这张二维码添加到body的子元素 放在最后或者是最前都可以,

注意这可能影响你的布局,可设置position:absolute,进行调整,因为这才是真正用来识别的二维码,如果这个二维码位置太偏移,有可能会造成二维码无法识别。此外还需要注意的是opacity需要设为0而不是设置display属性。

   <img style="position:absolute;width: XXpx;height: XXpx;opacity: 0" src="二维码图片地址"> 

   其次,在你应该在设计稿设计的地方,放置的div里面设置你正常二维码图片的大小,以便页面呈现正常。

   <img style="你的正常大小" src="二维码图片地址" />

   这时你就会发现长按图片能够识别出来二维码。

 

   其实除了这些BUG外,二维码信息显示不全;在长按时候只有部分可见;二维码周围信息过于复杂,在整个截屏中二维码算法无法正确识别;网页没有加载完成,微信的识别js没有启动都会导致二维码无法识别,另外二维码过大或者过小时,也会出现识别困难问题,通常160*160就可以了

 

此文章主要发布在本人所在公司网站H5案例分享(http://www.h5-share.com/)、公司公众号H5握手和个人博客中,转载请注明出处。

 

### 微信小程序 Canvas 实现识别二维码功能 在微信小程序中,通过 `Canvas` 绘制二维码并实现识别功能是一个常见的需求。以下是基于现有引用和技术细节的解决方案。 #### 1. 基本原理 为了实现识别二维码的功能,通常需要借助 HTML5 的 `Canvas` API 来绘制图像,并将其转换为可被微信扫码插件解析的形式。具体来说,可以通过以下方式完成: - 使用 `wx.canvasToTempFilePath` 将 Canvas 转换为临时文件路径。 - 利用微信内置的扫码能力处理生成的二维码图片[^2]。 #### 2. 示例代码 以下是一段完整的示例代码,展示如何在微信小程序中使用 Canvas 创建二维码,并提供识别功能: ```javascript // 在 WXML 文件中定义 Canvas 和按钮 <view> <canvas canvas-id="myCanvas" style="width: 300px; height: 300px;"></canvas> <button bindtap="saveAndScan">识别</button> </view> // 在 JS 文件中编写逻辑 Page({ data: { qrCodeUrl: 'https://example.com/qrcode', // 替换为目标二维码链接 }, onLoad() { this.drawQrCode(); }, drawQrCode() { const ctx = wx.createCanvasContext('myCanvas'); // 加载二维码图片 wx.getImageInfo({ src: this.data.qrCodeUrl, success(res) { const { width, height } = res; // 绘制二维码到 Canvas 上 ctx.drawImage(this.data.qrCodeUrl, 0, 0, 300, 300); ctx.draw(false, () => { console.log('二维码已绘制'); }); } }); }, saveAndScan() { // 将 Canvas 转换为临时文件路径 wx.canvasToTempFilePath({ canvasId: 'myCanvas', success(res) { const tempFilePath = res.tempFilePath; // 执行扫码操作 wx.scanCode({ filePath: tempFilePath, success(scanRes) { console.log('扫描结果:', scanRes.result); wx.showToast({ title: '识别成功' }); }, fail(err) { console.error('扫描失败:', err); wx.showToast({ title: '识别失败', icon: 'none' }); } }); }, fail(err) { console.error('Canvas 转换失败:', err); wx.showToast({ title: '生成二维码失败', icon: 'none' }); } }); } }); ``` #### 3. 关键点说明 - **Canvas 图像加载**:通过 `wx.getImageInfo` 获取远程二维码图片的信息,并调用 `drawImage` 方法将其渲染至 Canvas 中[^4]。 - **按触发事件**:虽然微信小程序本身未直接支持按手势绑定,但可通过模拟点击行为来间接实现此效果。 - **扫码接口调用**:利用 `wx.scanCode` 接口读取本地存储的二维码数据。 #### 4. 注意事项 - 确保目标二维码 URL 是有效的 HTTP(S) 地址。 - 如果涉及复杂样式(如背景图层叠加),需额外调整绘图顺序与参数设置[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值