問題概述
目前開發的App中涉及到以下場景:基於紙質發票的二維碼掃描結果,調用國稅總局的查詢接口,獲取發票的票面信息並自動構建對應的報銷單
發票二維碼中包含以下信息:
01,04,3200172320,39603420,110.68,20180526,07094405910702570327,9AE7,
國稅總局接口中需要以下信息進行查詢:
發票代碼:3200172320
發票號:39603420
開票日期:20180526
(普票)校驗碼后六位:570327
(專票)不含稅金額:110.68
目前App的二維碼掃描一般采用Zbar或者Zxing的解決方案,我們目前使用的是Zbar的掃描方案。該方案在掃描電子發票的二維碼以及打印清晰的二維碼時掃描迅速、准確。
但是在掃描紙質發票上的二維碼時基本無能為力,只有極少部分打印清晰,點陣整齊的發票可以掃描出來。
那我們首先來分析一下為什么無法掃描二維碼
二維碼生成規則簡析
二維碼生成原理<轉自>:https://coolshell.cn/articles/10590.html#jtss-tsina
原文比較長,撿重要的部分說一下
版本
二維碼分為40個版本(Version),第一個版本行、列格子數量為21 * 21,每增加一個版本,行、列各自數量各增加4,即版本為7的二維碼,行列格子數量都為 21 + 4*4= 37
區域
二維碼圖像從功能上分為以下區域:
定位區域:
用於幫助二維碼掃描器定位整體圖像以及切割數據信息的定位圖形,分為以下三種:
1.Position Detection Pattern:二維碼左上、左下、右上的定位正方形,正方形分為三部分:黑色外框,白色內框,黑色內正方形,其中寬度比例為:1:1:3,整體圖形寬度為 7
2.Alignment Pattern:二維碼內部用於輔助定位的正方形結構,分為三部分:黑色內框,白色內框,黑色內正方形,其中寬度比例為1:1:3,整體圖形寬度為5,該定位圖形在版本2以上的二維碼中存在
3.Timing Pattern:二維碼內部定義行列基准的輔助線,幫助掃描器識別每個行列的基准位置
元數據區域:
用於描述二維碼的本身的格式以及版本信息的數據區域,分為以下兩部分:
1.Format Information:存在於所有的尺寸中,用於存放一些格式化數據,包括:Error Correction Level(錯誤糾正等級)、Mask(掩碼類型)
2.Version Information:Version 7以上,需要預留兩塊3 x 6的區域存放一些版本信息
數據以及糾錯碼區域:
除了上述的那些地方,剩下的地方存放 Data Code 數據碼 和 Error Correction Code 糾錯碼。最終編碼的填充方式如下:從左下角開始沿着紅線填我們的各個bits,1是黑色,0是白色。如果遇到了上面的非數據區,則繞開或跳過。
發票二維碼解析問題簡析
二維碼掃描器列舉以及原理分析
目前市面上有很多App自帶了二維碼掃描,經過測試,我們得出以下結論:
二維碼掃描能力:阿里系(支付寶、釘釘) > 騰迅系(微信、QQ)> 第三方收費插件 > 蘋果相機自帶二維碼掃描 > ZBar方案 > Zxing方案
阿里的掃描器基本可以掃描出所有的發票二維碼,很多殘缺的二維碼圖像也可以掃描出來,而且掃描的速度非常快。騰訊的掃描器可以掃描出完整的二維碼,即使出現圖像偏色、部分模糊的問題,掃描速度稍遜於阿里。第三方收費插件對偏色和部分模糊的處理稍微差一些。蘋果自帶的二維碼掃描可以掃描出打印清晰、整齊的二維碼,編碼部分出現線段粗細不一致和部分空白也可以掃描。Zbar和Zxing對發票二維碼基本無能為力。
Tips:手淘對發票二維碼的掃描率遠低於釘釘,應該是釘釘對企業的應用場景做了更深入層次的優化
我們對二維碼掃描器的工作原理進行分析,掃描器應當是對一張圖片進行二維碼的特征提取,例如Position Detection Pattern和Alignment Pattern,檢索出整體圖形大致形狀,然后通過Timing Pattern建立掃描坐標體系,再掃描元數據區域,確認解碼方案,然后根據坐標體系對數據以及糾錯碼區域進行掃描和數據分割,獲取已編碼數據,最后根據解碼方案反向解碼獲得二維碼的實際信息。
根據對zxing和zbar的測試,掃描器對結構清晰、整齊的二維碼掃描很快,說明當來源圖片清晰的時候,掃描器可以順利的構建特征和坐標,並最終解碼。當掃描發票時,由於發票的特征和坐標存在缺陷,導致掃描器無法正確識別。
由於整體二維碼解碼過程比較復雜,且已經有很好的開源庫支持,所以我們的目標不是重新寫一個解碼器,而是通過一些算法將發票上不明確的二維碼特征值提取出來,重新構建一個標准的二維碼圖形,並輸送給zxing或者zbar進行解碼。
發票二維碼實例分析
1.清晰二維碼:可識別掃描器:全部
2.偏色二維碼:可識別掃描器:支付寶
3.差色二維碼:可識別掃描器:支付寶、微信,當手機處於靜態狀態的時候,支付寶和微信對這個二維碼掃描識別率都很低,但是當手機攝像頭整體晃動的時候,支付寶和微信對這個二維碼都可以迅速識別。無法理解的黑科技
4.干擾二維碼:可識別掃描器:支付寶、微信、蘋果相機自帶、第三方插件
5.部分糊化二維碼:可識別掃描器:支付寶、微信、蘋果相機自帶、第三方插件、Zbar
6.整體糊化二維碼:可識別掃描器:支付寶、微信
7.線條寬度殘缺:可識別掃描器:支付寶
8.定位圖形缺損:可識別掃描器:支付寶,從實際收集到的發票來看,這種問題的發票數量比較多,迫切需要解決
從測試結果來看,支付寶對偏色、差色、線條干擾、糊化、殘缺的二維碼圖片都有很好的識別率。微信對圖形完整的二維碼有很好的識別率,當圖片出現殘損的時候沒有對應的策略。
蘋果自帶相機的掃描效果要好於Zbar方案,如果做二維碼掃描的同學在IOS端可以考慮直接調用蘋果相機自帶的掃描。
該篇主要是對二維碼的原理進行了簡介,對目前發票二維碼掃描的問題點進行了簡要分析,后續對改進的方案進行介紹。