Android實現二維碼掃描功能(二)-ZXing個性化與近距離識別優化
簡介
本篇我們對掃碼介面進行優化,並對ZXing近距離無法識別的問題做出優化。
個性化定製
每個APP都有自己的表現形式,實現個性化掃碼介面定製,主要有兩個地方:
- activity_scanner.xml介面檔案
- 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智能設