1. 程式人生 > >Android實現二維碼掃描功能(二)-ZXing個性化與近距離識別優化

Android實現二維碼掃描功能(二)-ZXing個性化與近距離識別優化

簡介

本篇我們對掃碼介面進行優化,並對ZXing近距離無法識別的問題做出優化。

個性化定製

每個APP都有自己的表現形式,實現個性化掃碼介面定製,主要有兩個地方:

  1. activity_scanner.xml介面檔案
  2. com.google.zxing.view.ViewfinderView掃碼控制元件

下面分別來說明。

介面檔案

activity_scanner.xml原始碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<include layout="@layout/toolbar_scanner" /> <FrameLayout android:layout_width="match_parent" android:layout_height
="match_parent">
<SurfaceView android:id="@+id/scanner_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" /> <com.google.zxing.view.ViewfinderView android:id
="@+id/viewfinder_content" android:layout_width="wrap_content" android:layout_height="wrap_content" app:corner_color="@color/corner_color" app:frame_color="@color/viewfinder_frame" app:label_text="二維碼/條形碼掃描" app:label_text_color="@color/colorAccent" app:laser_color="@color/laser_color" app:mask_color="@color/viewfinder_mask" app:result_color="@color/result_view" app:result_point_color="@color/result_point_color" />
</FrameLayout> </LinearLayout>

介面分析:

  • 頂層採用LinearLayout實現自上至下的方向,基本不用修改;
  • <include layout="@layout/toolbar_scanner" />引用toolbar佈局檔案,稍後給出,這裡可以加入選單專案、返回鍵等;
  • FrameLayout佈局將相機可掃描視窗疊加在一起;
  • SurfaceView裝載相機內容,即相機拍攝到的畫面;
  • com.google.zxing.view.ViewfinderView掃碼自定義View,主要由遮罩層、四個角的邊框、掃描線等組成。

toolbar_scanner.xml,比較簡單

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:contentInsetStart="0dip">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical">

        <ImageButton
            android:id="@+id/btn_back"
            android:layout_width="40dip"
            android:layout_height="40dip"
            android:background="?attr/selectableItemBackground"
            android:padding="10dip"
            android:scaleType="centerCrop"
            android:src="@drawable/btn_back" />

        <TextView
            android:id="@+id/txt_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="掃描二維碼"
            android:textColor="@android:color/white"
            android:textSize="18sp" />

    </RelativeLayout>
</android.support.v7.widget.Toolbar>

可根據需求調整toolbar內容,這裡我們就不多說。

掃碼控制元件定製

現行使用的ViewfinderView已經是經過前輩修改過的版本,他們加入了邊框和掃描線,基於這個版本我們再做一些調整。

1、提示文字的位置

現有的提示文字是在掃描框上面的
這裡寫圖片描述
我們需要把它放置到掃描框下面,需要將原始碼中drawTextInfo方法調整一下:

//繪製文字
  private void drawTextInfo(Canvas canvas, Rect frame) {
    ...
    canvas.drawText(labelText, frame.left + frame.width() / 2, frame.top - CORNER_RECT_HEIGHT, paint);
  }

調整為:

//繪製文字
  private void drawTextInfo(Canvas canvas, Rect frame) {
    ...
    canvas.drawText(labelText, frame.left + frame.width() / 2, frame.bottom + CORNER_RECT_HEIGHT * 1.5f, paint);
  }

此處通過修改drawText的y座標引數調整了文字位置,可以根據需要自行調整。

2、掃碼框的位置

目前的掃碼框整體位置偏下,不夠美觀,打算將位置往上調整一些。
修改com.google.zxing.camera.CameraManager類中的getFramingRect()方法,由

public Rect getFramingRect() {
        ...
        int leftOffset = (screenResolution.x - width) / 2;
        int topOffset = (screenResolution.y - height) / 2;
        ...

        return framingRect;
}

修改為

public Rect getFramingRect() {
        ...
        int leftOffset = (screenResolution.x - width) / 2;
        int topOffset = (screenResolution.y - height) / 3;
        ...

        return framingRect;
}

即topOffset有了減小,預覽後如:
這裡寫圖片描述

3、掃碼框大小
由2我們可以看到getFramingRect()方法構造的矩形中有寬、高參數,通過修改這兩個引數,可以完成掃碼框大小變更。例如:

public Rect getFramingRect() {
        ...
        int width = screenResolution.x * 8 / 10;
        int height = screenResolution.y * 8 / 10;
        ...

        return framingRect;
}

則比原來的程式碼中放大了1/10,預覽圖(可對比2中圖):
這裡寫圖片描述

掃碼識別優化

這裡主要說一下近距離掃碼識別不了的問題,關於掃碼演算法的改進涉獵不多,文尾給大家一篇文章參考。

ZXing在遇到二維碼撐滿掃碼框的情況下識別不出結果,等多久、再聚焦都不可以,有朋友說擴大掃碼框的大小可以解決這個問題,擴大後近距離掃碼結果還是一致的,很難識別出來。

原因是原演算法對攝像頭採集的影象畫素進行了裁剪,真正返回給識別演算法的影象可能沒有掃碼框那麼完整。

參考網路大神的帖子,我們將com.google.zxing.camera.CameraManager類中的buildLuminanceSource方法做了調整,不再返回剪裁後的影象。原始碼:

public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
        Rect rect = getFramingRectInPreview();
        int previewFormat = configManager.getPreviewFormat();
        String previewFormatString = configManager.getPreviewFormatString();
        switch (previewFormat) {
            // This is the standard Android format which all devices are REQUIRED to support.
            // In theory, it's the only one we should ever care about.
            case PixelFormat.YCbCr_420_SP:
                // This format has never been seen in the wild, but is compatible as we only care
                // about the Y channel, so allow it.
            case PixelFormat.YCbCr_422_SP:
                return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
                        rect.width(), rect.height());
            default:
                // The Samsung Moment incorrectly uses this variant instead of the 'sp' version.
                // Fortunately, it too has all the Y data up front, so we can read it.
                if ("yuv420p".equals(previewFormatString)) {
                    return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
                            rect.width(), rect.height());
                }
        }
        throw new IllegalArgumentException("Unsupported picture format: " +
                previewFormat + '/' + previewFormatString);
    }

修改為:

public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
        Rect rect = getFramingRectInPreview();
        int previewFormat = configManager.getPreviewFormat();
        String previewFormatString = configManager.getPreviewFormatString();
        switch (previewFormat) {
            // This is the standard Android format which all devices are REQUIRED to support.
            // In theory, it's the only one we should ever care about.
            case PixelFormat.YCbCr_420_SP:
                // This format has never been seen in the wild, but is compatible as we only care
                // about the Y channel, so allow it.
            case PixelFormat.YCbCr_422_SP:
                return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height);
            default:
                // The Samsung Moment incorrectly uses this variant instead of the 'sp' version.
                // Fortunately, it too has all the Y data up front, so we can read it.
                if ("yuv420p".equals(previewFormatString)) {
                    return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height);
                }
        }
        throw new IllegalArgumentException("Unsupported picture format: " +
                previewFormat + '/' + previewFormatString);
    }

主要改動的是new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height); 實際上就是將完整的相機影象內容返回,不做裁剪。

結語

本篇對ZXing掃碼工具介面定製和掃碼識別優化做了講解,解決了ZXing近距離無法識別二維碼的問題。
大家也可以順著這個思路,做更多個性化定製和優化,完善掃碼功能。

參考資料

原始碼下載

相關推薦

Android實現掃描功能-ZXing個性化距離識別優化

簡介 本篇我們對掃碼介面進行優化,並對ZXing近距離無法識別的問題做出優化。 個性化定製 每個APP都有自己的表現形式,實現個性化掃碼介面定製,主要有兩個地方: activity_scanner.xml介面檔案 com.google.zxin

Android實現掃描功能-閃光燈控制

簡介 本篇我們對光線暗淡情況下閃光燈的使用做出介紹。 效果 晚上測試時: 開燈後: 未開燈: 實現步驟 1、在activity_scanner.xml介面上加上閃光燈開關按鈕。可以是Button、Checkbox等控制元件。

Android掃描開發實現思路原理

【 回覆“ 1024 ”,送你一個特別推送 】 現在二維碼已經非常普及了,那麼二維碼的掃描與處理也成為了Android開發中的一個必要技能。網上有很多關於Android中二維碼處理的帖子,大都是在講開源框架zxing用法,然後貼貼程式碼就完了,並沒有一個系統的分析和

Android 基於google Zxing實現、條形碼掃描,仿微信掃描效果現在正做個掃描App、收藏

瞭解二維碼這個東西還是從微信中,當時微信推出二維碼掃描功能,自己感覺挺新穎的,從一張圖片中掃一下竟然能直接加好友,不可思議啊,那時候還不瞭解二維碼,呵呵,然後做專案的時候,老闆說要加上二維碼掃描功能,然後自己的屁顛屁顛的去百度,google啥的,發現很多朋友都

Android開發之Zbar實現掃描功能

前言: 在寫這篇文章之前已經寫過兩篇關於二維碼功能的文章,有興趣的可以看看——》文章1:Android開發之利用ZXing庫實現二維碼的掃描;文章2:Android開發之利用ZXing庫實現二維碼的生成,這兩篇文章中使用到的二維碼生成庫是ZXing,在本篇

Android 基於zxing掃描功能的簡單實現優化

由於專案中需要接入一下簡單的二維碼掃描功能,最終使用 zxing 來實現,把官方例子中的部分程式碼摘除出來做了簡單的封裝,並進行了一些優化。這裡簡單做一個記錄。 掃描二維碼 Android 中關於二維碼掃描的庫有很多,但是歸根到底無外乎下面這幾種

Android中Webview原生介面互動及掃描功能實現

最近專案中有一個新的需求,大致是這樣的:APP中通過WebView展示一個第三方的HTML5介面,使用者可以在HTML5介面中呼叫Android攝像頭進行二維碼掃描,並將掃描結果顯示在HTML5介面。這顯然涉及到了Android原生與WebView之前的傳值

Android之在Fragment中使用掃描功能

最近在做一個專案,是在Fragment中使用zxing的二維碼掃描功能,在我以前寫的二維碼掃描功能的教程只適合在activity中使用地址:https://blog.csdn.net/qq_31844349/article/details/81301911 沒有辦法因為工作需要,必須在Fra

html5掃描功能實現

html5中可以使用二維碼掃描,也可以從相簿中選擇二維碼識別,程式碼如下 var ws = null, wo = null; var scan = null, domr

phonegap的掃描功能實現

    首先簡單的介紹下DOS環境下phonegap專案的結構,如下圖:    如果大家的專案結構和上圖中專案結構一樣,就可以按照下面的步驟來實現掃描二維碼的功能了,不一樣的下面的步驟也可以提供一定的參考。 ####################START#######

Android開發中的掃描功能

Android開發中的二維碼掃描 現在Android開發中使用二維碼掃描功能越來越多,本篇部落格具體講一下其使用方法: 新增依賴 在自己的Activity或者Fragment中使用新增關於掃描的連結 新增二維碼掃描的相關Activity 對掃描資料進

基於MUI框架的使用HTML5+實現掃描功能並且其結果在webview中的資訊的傳遞

<!doctype html> <html> <head> <meta charset="UTF-8"> <title></title> <meta name="viewport" content="width=d

react-native-smart-barcode目前最好用的掃描元件IOS、android

最近在製作React-Native專案的時候,條碼識別給我們整個專案帶了不少麻煩,幾款主流的條碼識別元件都不是特別好用,使用者體驗比較差,比如二維碼識別速度慢、掃描頁面十分卡頓用等一系列問題,後來在網上無意間找到一個非常好用的二維碼掃描元件——react-native-smart-barcode,這個元件是

ios-實現掃描功能

在此就簡單的介紹下二維碼掃描功能的實現把 首先先說下思路,我們需要去配置的就是   1、輸入裝置(用來獲取外界資訊),輸入裝置有攝像頭、麥克風、鍵盤   2、輸出裝置(將收集到的資訊進行解析去獲取收到的內容)   3、會話的session(用來連線輸入和輸出的裝置),不然的

基於MUI框架的使用HTML5+實現掃描功能

<!doctype html> <html> <head> <meta charset="UTF-8"> <title></title> <meta name="viewport" content="width=devi

H5+ 掃描功能

二維碼在生活中的使用越來越廣泛,APP開發中,也越來越多的需求需要用到二維碼的掃描功能,以下就針對h5+的二維碼掃描功能做一些簡單的介紹; 1. var bc = new plus.barc

ionic3 掃描外掛 Barcode Scanner 和 Zbar和 QR Scanner的戰鬥

三款ionic的掃描外掛。 各大部落格都有他們的介紹,我也不想贅述多少。 總結了下各大博主說的,反正是好壞都有,我給各位列個表格自己判斷吧 Barcode Scanner 速度慢,樣式機會為零 Zbar 速度快,ios樣式幾乎為零(槽點:連文字和木紋

C# TSC列印和條形碼 C#呼叫dll提示"試圖載入格式不正確的程式"解決方法

效果圖   開發、使用環境說明 安裝TSC_7.3.8_M-3.exe印表機驅動,安裝時選擇對應的ttp 244 pro 將TSCLIB.dll複製到C:\Windows\system 驅動安裝說明     選擇下一步   &nbs

掃描和生成

1.佈局 <?xml version="1.0" encoding="utf-8"?> <cn.bingoogolapple.qrcode.zxing.ZXingView android:id="@+id/zxing" and

你不知道的掃描模組、讀頭行業應用?

終端 熱門行業 roc 系統 哪些 mark 門禁 cto ext 隨著二維碼識別技術的發展,近些年以二維碼掃描模組為核心掃碼硬件無論是生活還是工作,都給我們帶來了前所未有的改變。設備掃描讀取乘車碼乘坐公交地鐵、在自助機上刷支付寶微信付款碼實現二維碼支付等一系列O2O智能設