1. 程式人生 > >二維碼生成、掃描、圖片識別(Zxing)

二維碼生成、掃描、圖片識別(Zxing)

這樣的例子雖然已經很多了,不過我在網上瀏覽了一圈,也沒找到幾個相簿二維碼圖片識別例子,好的演算法識別率才高。這裡有一個好點的演算法,演算法不是我寫的,只是作為整理記錄,給眾多安卓開發者一個方便。demo的UI有點low,不過功能卻是實實在在,有需要的朋友可以自定義一些UI介面。我寫demo得時候就不費那勁了。

看看截圖功能。


點選生成二維碼,傳入一個字串,生成相應的二維碼。


生成二維碼返回的是一個bitmap,很好處理,簡單實用。點選開始掃描


進入掃描介面,右上角有兩個按鈕,一個是開啟手機閃光燈,一個是手機相簿選取圖片解析。

只要掃描成功,就會有一個回撥介面,在回撥介面做相應處理。下面的圖片是掃描成功和圖片解析成功回撥的介面。


功能介紹的差不多了,看看程式碼。首先匯入Zxing 的gradle

//二維碼掃描、識別、生成
    compile 'com.google.zxing:core:3.2.1'

然後在git上下載原始碼demo,取其中的QRlibrary的資料夾,匯入你的專案。



點選確定,然後等待編譯就ok了。之後再建立你的專案與QRlibrary的依賴。



選擇了Module依賴之後,選擇QRlibrary,確定之後等待編譯。在你的專案中建立一個類QRScanActivity(這裡是建立一個類,而不是Activity,當然也要在application中註冊,只是不需要建立xml檔案)繼承QRCode2ScanActivity,重寫以下方法即可。handleDecode是二維碼掃描成功回撥介面,掃描成功之後在這裡寫之後的邏輯。


圖片解析成功回撥的方法,也就是onActivityResult,當然還必須呼叫解析的方法。


圖片解析邏輯單獨貼出來

                    String[] proj = { MediaStore.Images.Media.DATA };
                    // 獲取選中圖片的路徑
                    Cursor cursor = getContentResolver().query(data.getData(),
                            proj, null, null, null);

                    if (cursor.moveToFirst()) {

                        int column_index = cursor
                                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        photo_path = cursor.getString(column_index);
                        if (photo_path == null) {
                            photo_path = Utils.getPath(getApplicationContext(),
                                    data.getData());
                            Log.i("123path  Utils", photo_path);
                        }
                        Log.i("123path", photo_path);
                    }

                    cursor.close();

                    new Thread(new Runnable() {

                        @Override
                        public void run() {

                            Result result = scanningImage(photo_path);
                            // String result = decode(photo_path);
                            if (result == null) {
                                Log.i("123", "   -----------");
                                Looper.prepare();
                                Toast.makeText(getApplicationContext(), "圖片格式有誤",Toast.LENGTH_SHORT)
                                        .show();
                                Looper.loop();
                            } else {
                                Log.i("tag00", result.toString());
                                // Log.i("123result", result.getText());
                                // 資料返回
                                String recode = recode(result.toString());
                                startActivity(new Intent(QRScanAtivity.this,ResultActivity.class).putExtra("result", recode));
                                finish();
                            }
                        }
                    }).start();
這段程式碼需要在onActivityResult中呼叫。

我在我的專案中匯入library之後,建立了一個QRScanActivity,粘出所有邏輯

public class QRScanAtivity extends QRCode2ScanActivity {

    private static final int REQUEST_CODE = 234;
    private String photo_path;
    @Override
    public void handleDecode(Result rawResult, Bundle bundle) {
        super.handleDecode(rawResult, bundle);
        //掃描成功,回撥的方法
        inactivityTimer.onActivity();

        bundle.putString("result", rawResult.getText());

        startActivity(new Intent(QRScanAtivity.this, ResultActivity.class).putExtras(bundle));
        finish();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {

            switch (requestCode) {

                case REQUEST_CODE:

                    String[] proj = { MediaStore.Images.Media.DATA };
                    // 獲取選中圖片的路徑
                    Cursor cursor = getContentResolver().query(data.getData(),
                            proj, null, null, null);

                    if (cursor.moveToFirst()) {

                        int column_index = cursor
                                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        photo_path = cursor.getString(column_index);
                        if (photo_path == null) {
                            photo_path = Utils.getPath(getApplicationContext(),
                                    data.getData());
                            Log.i("123path  Utils", photo_path);
                        }
                        Log.i("123path", photo_path);
                    }

                    cursor.close();

                    new Thread(new Runnable() {

                        @Override
                        public void run() {

                            Result result = scanningImage(photo_path);
                            // String result = decode(photo_path);
                            if (result == null) {
                                Log.i("123", "   -----------");
                                Looper.prepare();
                                Toast.makeText(getApplicationContext(), "圖片格式有誤",Toast.LENGTH_SHORT)
                                        .show();
                                Looper.loop();
                            } else {
                                Log.i("tag00", result.toString());
                                // Log.i("123result", result.getText());
                                // 資料返回
                                String recode = recode(result.toString());
                                //解析成功之後,recode是解析成都的字串,這裡對其做資料處理
                                startActivity(new Intent(QRScanAtivity.this,ResultActivity.class).putExtra("result", recode));
                                finish();
                            }
                        }
                    }).start();
                    break;

            }

        }
    }
}
二維碼生成,掃描還有圖片解析,運用就是這些了。具體原始碼邏輯就不細談了。我把原始碼放在git上,有興趣想要了解是如何實現的朋友,那就自己去看原始碼吧。

#如果覺得有用,請幫忙點頂一下,謝謝。