近來在寫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握手和個人博客中,轉載請注明出處。