二维码扫描在日常的使用中非常广泛,特总结一波,并比较zxing与zbar的优劣之处
zxing与zbar对比:
1.zxing是谷歌开源,项目地址为:https://github.com/zxing/zxing,仍在维护,采用C++编写。zbar则是主要用C来写的,速度极快,推出了iPhone的SDK和Android的相关调用方法(JNI),但这个项目已经有几年不维护了,项目地址: https://github.com/ZBar/ZBar。
2.zxing支持更多的码制:datamatix、PDF417、等,zbar不能很好支持PDF417(但是在源码中有对于Pdf417码处理)
3.zxing的执行解码效率低于zbar,从耗费内存空间角度看,zbar更适合嵌入式设备开发,大部分手机app的解码采用的是zxing,因为zxing当初就是面向android开发的。
4.zbar和zxing 两者都不能 很好的支持 条码扫描,在摄像头分辨率低,目标条码打印在曲面上或者目标条码密集或扫描角度非垂直的情况下,很难识别,且条码扫描会产生误读,这种致命缺点致使激光扫描头任然为条码识读领域的工业级设备。
我使用的是第三方库:BGAQRCode-Android
同时支持zxing和zbar,使用比较简单,使用步骤如下:
1.申请权限
<!--二维码扫描权限-->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
2.添加依赖
// 一下两个使用哪个就添加哪个的依赖
implementation "cn.bingoogolapple:bga-qrcode-zxing:$bga_qrcode"
implementation "cn.bingoogolapple:bga-qrcode-zbar:$bga_qrcode"
$bga_qrcode 为引用的值:1.2.5
3.相关代码
主界面布局
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_zbar:
if (hasPermission) {
startActivity(new Intent(this,ScanActivity.class));
}
break;
case R.id.btn_zxing:
if (hasPermission) {
startActivity(new Intent(this,ZxingScanActivity.class));
}
break;
default:
break;
}
}
两个按钮,分别是采用zxing和zbar开启二维码扫描界面,这里注意要处理拍照的运行时权限,不再赘述。以zbar为例:
ScanActivity 界面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<cn.bingoogolapple.qrcode.zbar.ZBarView
android:id="@+id/zbarview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:qrcv_animTime="1000"
app:qrcv_barCodeTipText="将条码放入框内,即可自动扫描"
app:qrcv_barcodeRectHeight="120dp"
app:qrcv_borderColor="@android:color/white"
app:qrcv_borderSize="1dp"
app:qrcv_cornerColor="@color/colorPrimaryDark"
app:qrcv_cornerLength="20dp"
app:qrcv_cornerSize="3dp"
app:qrcv_customGridScanLineDrawable="@drawable/custom_grid_scan_line"
app:qrcv_isBarcode="false"
app:qrcv_isOnlyDecodeScanBoxArea="false"
app:qrcv_isShowDefaultGridScanLineDrawable="true"
app:qrcv_isShowDefaultScanLineDrawable="true"
app:qrcv_isShowLocationPoint="false"
app:qrcv_isShowTipBackground="true"
app:qrcv_isShowTipTextAsSingleLine="false"
app:qrcv_isTipTextBelowRect="false"
app:qrcv_maskColor="#44000000"
app:qrcv_qrCodeTipText="将二维码放入框内,即可自动扫描"
app:qrcv_rectWidth="200dp"
app:qrcv_scanLineColor="@color/colorPrimaryDark"
app:qrcv_toolbarHeight="56dp"
app:qrcv_topOffset="80dp"
app:qrcv_verticalBias="-1" />
<ImageView
android:layout_marginBottom="100dp"
android:id="@+id/open_flashlight"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/flashlight_off" />
</FrameLayout>
简单说明一下:关键是通过 cn.bingoogolapple.qrcode.zbar.ZBarView 来开启并控制二维码扫描,ImageView作为控制闪光灯的开启按钮。
ScanActivity 相关代码:
public class ScanActivity extends AppCompatActivity implements Delegate, View.OnClickListener {
private static final String TAG = "ScanActivity";
private ZBarView mZBarView;
private boolean open_flashlight = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zbar_scan);
mZBarView = findViewById(R.id.zbarview);
mZBarView.setDelegate(this);
findViewById(R.id.open_flashlight).setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
mZBarView.startCamera(); // 打开后置摄像头开始预览,但是并未开始识别
mZBarView.startSpotAndShowRect(); // 显示扫描框,并且延迟0.5秒后开始识别
}
@Override
protected void onStop() {
mZBarView.stopCamera(); // 关闭摄像头预览,并且隐藏扫描框
super.onStop();
}
@Override
protected void onDestroy() {
mZBarView.onDestroy(); // 销毁二维码扫描控件
super.onDestroy();
}
private void vibrate() {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(200);
}
@Override
public void onScanQRCodeSuccess(String result) {
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
vibrate();
// 延迟0.5秒后开始识别
mZBarView.startSpot();
}
@Override
public void onScanQRCodeOpenCameraError() {
Log.e(TAG, "打开相机出错");
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.open_flashlight:
handleFlashLight();
break;
default:
break;
}
}
private void handleFlashLight() {
open_flashlight = !open_flashlight;
if (open_flashlight) {
mZBarView.openFlashlight();
} else {
mZBarView.closeFlashlight();
}
}
}
可以参考作者原项目的demo,非常容易使用,zxing与zbar在使用上的区别主要是界面中扫描控件不一样,其他使用方式大体一样。也可以参见该篇博客:https://blog.csdn.net/fanxudonggreat/article/details/76595587,有更详细的使用说明。
最后附上我demo地址:https://github.com/YuPf1989/Samples/tree/master
参考文章:
1.https://blog.csdn.net/l_215851356/article/details/51898514
2.https://blog.csdn.net/u014290023/article/details/40349839