天天看點

ZXing實作掃描或選取圖檔識别二維碼及條碼功能一、了解二維碼二、項目內建ZXing三、實作選取圖檔識别二維碼功能四、功能調用及結果處理

最近項目中需要內建掃一掃功能,在網上翻閱資料以後,內建了zxing最新的代碼,并參考實作了選取圖檔識别二維碼功能,整體效果堪比微信掃一掃功能。網上資料浩如煙海,可用者無幾,故于此文記錄個人代碼內建過程,及有用資料,以供查閱。

一、了解二維碼

生成二維碼的網站可用于測試:草料二維碼

參考資料:二維碼(QR code)基本結構及生成原理

二維碼 (2-dimensional bar code),是用某種特定的幾何圖形按一定規律在平面(二維方向上)分布的黑白相間的圖形記錄資料符号資訊的。

在許多種類的二維條碼中,常用的碼制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。

二維條碼/二維碼可以分為堆疊式/行排式二維條碼和矩陣式二維條碼。其中矩陣式二維碼因QR CODE而廣泛流行,我們現在所說的二維碼一般即指QR CODE。

QR(Quick-Response) code是被廣泛使用的一種二維碼,解碼速度快。具有以下特點:1.存儲大容量資訊;2.在小空間内列印;3.有效表現各種字母(1994年由日本DW公司發明);4.對變髒和破損的适應能力強;5.可以從任意方向讀取(三處定位圖案);6.支援資料合并功能。

QR code包括:QR碼(模型1模型2),Micro QR碼,iQR碼。

QR code的基本結構如下:

ZXing實作掃描或選取圖檔識别二維碼及條碼功能一、了解二維碼二、項目內建ZXing三、實作選取圖檔識别二維碼功能四、功能調用及結果處理

二維碼基本結構

位置探測圖形、位置探測圖形分隔符、定位圖形:用于對二維碼的定位,對每個QR碼來說,位置都是固定存在的,隻是大小規格會有所差異;

校正圖形:規格确定,校正圖形的數量和位置也就确定了;

格式資訊:表示改二維碼的糾錯級别,分為L、M、Q、H;

版本資訊:即二維碼的規格,QR碼符号共有40種規格的矩陣(一般為黑白色),從21x21(版本1),到177x177(版本40),每一版本符号比前一版本 每邊增加4個子產品。

資料和糾錯碼字:實際儲存的二維碼資訊,和糾錯碼字(用于修正二維碼損壞帶來的錯誤)。

QR碼的編碼過程:1.資料分析;2.資料編碼;;3.糾錯編碼;4.構造最終資料資訊;5.構造矩陣;6.掩摸;7.格式和版本資訊。

QR碼的解碼過程:有興趣可查閱:如何筆算解碼二維碼?

以上文本摘抄自參考資料,具體概念請查閱原文。

二、項目內建ZXing

參考資料:Google ZXing系列講解(一)——導入AS

內建ZXing的方法可以分為三種:

1、jar包導入;

2、下載下傳源碼以依賴庫的方式導入;

3、直接将源碼整合到項目當中。

許多人在網上推薦自己的開源項目,對ZXing加工瘦身後可直接通過maven導入。在網上嘗試部分項目後,發現效果都不太理想,主要是瘦身後導緻掃描速度慢,源碼過于老舊,部分新功能沒有等問題。個人推薦直接下載下傳源碼,整合到項目中,一來便于對掃描界面及CaptureActivity.java進行定制,二來可以自行删除不需要的功能的代碼(生成二維碼,設定,掃描曆史等功能),減少無用代碼的占用。具體整合方法見參考資料,這裡就不再贅述。

三、實作選取圖檔識别二維碼功能

參考資料:使用ZXing掃碼實作掃手機本地圖檔的二維碼内容

實作選取圖檔識别二維碼功能主要包括以下步驟:1、跳轉本地相冊選取圖檔;2、選擇圖檔并傳回圖檔位址;3、根據圖檔位址擷取圖檔并轉換為bitmap;4、解析bitmap二維碼并傳回結果。

之前用其他方法實作後,會出現如果圖檔中除了二維碼還有其他文本,那麼就會導緻掃描失敗的情況。解決方法在于轉化為bitmap後,調用以下方法:

result =new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(source)), HINTS);

其中decode()調用decodeInternal()方法,decodeInternal()方法源碼如下:

ZXing實作掃描或選取圖檔識别二維碼及條碼功能一、了解二維碼二、項目內建ZXing三、實作選取圖檔識别二維碼功能四、功能調用及結果處理

通過對bitmap重複解析以獲得解析結果或抛出解析失敗異常。這樣即使二維碼隻占圖中的一部分,也能解析得到結果。

調用該方法為耗時操作,需要線上程中進行。具體代碼請查閱參考資料。

四、功能調用及結果處理

實作完以上兩步,在ZXing源碼的CaptureActivity中有兩處可獲得識别結果。

第一處:處理掃描結果:

public void handleDecode(Result rawResult, Bitmap barcode,float scaleFactor){

    //根據掃描結果,通過Intent傳回最終結果

    String content = rawResult.getText();

    String resultStr = recode(content);

    Intent intentRet =new Intent();

    intentRet.putExtra("strRet",resultStr);

    setResult(RESULT_OK,intentRet);

    finish();

}

第二處:處理圖檔識别結果:

private void prasePhoto(final String path) {

    @Override

    protected void onPostExecute(String content) {

        // 識别出圖檔二維碼/條碼,内容為content,同樣通過Intent傳回最終結果

        Intent intentRet =new Intent();

        intentRet.putExtra("strRet",content);

        setResult(RESULT_OK,intentRet);

        finish();

    }

}

最後,需要獲得調用掃描功能的類中,通過startActivityForResult()方法調用CaptureActivity類,并在onActivityResult()類中對結果進行處理。

if(resultCode == Activity.RESULT_OK){

    String retDiag = data.getStringExtra("strRet");

    //根據需求對最終結果retDiag進行處理

}

到此,就完成了對掃描功能的整合。二維碼掃描功能開發完成。有些人可能需要對掃描框進行定制,隻需要在ViewfinderView類中對getView()進行修改即可。