Android Zbar和Zxing

Android中用于二维码相关的库比较少,并且大多数已经不再维护(具体可见https://android-arsenal.com/tag/81)。其中最常用的是zxing和zbar,zxing项目是谷歌推出的用来识别多种格式条形码的开源项目,项目地址为https://github.com/zxing/zxing,zxing有多个人在维护,覆盖主流编程语言,也是目前还在维护的较受欢迎的二维码扫描开源项目之一。zbar则是主要用C来写的,速度极快,推出了iPhone的SDK和Android的相关调用方法(JNI),但这个项目已经有几年不维护了,目前并没有维护下去的意思,见https://github.com/ZBar/ZBar

Paste_Image.png

二维码优化

优化其实我觉得有两方面
(1)优化二维码生成算法,因为现在有专门做二维码的公司,说明二维码是可以做的更好识别的(微信扫二维码之所快,他们扫描的算法是一方面,但是二维码生成也是优化的)
(2)优化二维码的扫描算法

Zxing

zxing 的Demo修改后实现的扫描最大的问题就是角度,用zxing做的扫描需要与二维码差不多完全平行才能扫出来(图片识别出了问题),优化下zxing

  • 项目工程代码优化
    去掉不必要的类,比如我们的目的是扫描二维码,但其实原github上Zxing的Demo是可以扫描条形码,扫描获取到图片之后它会进行判断,类似的多余类去掉可以稍微提升一下速度(主要是使工程不那么臃肿)


    Paste_Image.png
  • 扩大扫描区域
    默认的是扫描框中才能识别二维码,但是你可以把扫描范围变大,我将扫描改成整个手机屏幕,这样,在识别的过程中,可能二维码还没整个进入框中,就已经识别出来了,让人觉得识别速度很快(缺点貌似就是生成的图像的数据变大,对手机的性能会有一定的要求,但是现在的手机基本都没问题)
  • 二分值算法
    二维码扫描精度和许多因素有关,最关键的因素是扫描算法。目前在图形识别领域中,较常用的二维码识别算法主要有两种,分别是HybridBinarizer和GlobalHistogramBinarizer这两种算法都是基于二值化,即将图片的色域变为黑白两个颜色,然后提取图形中的二维码矩阵。
    实际上,zxing中的HybridBinarizer继承GlobalHistogramBinarizer,并在此基础上做了功能性的改进。GlobalHistogramBinarizer算法适合于低端的设备,对手机的CPU和内存要求不高。但它选择了全部的黑点来计算,因此无法处理阴影和渐变这两种情况。HybridBinarizer算法在执行效率上要慢于GlobalHistogramBinarizer算法,但识别相对更有效。它专门为以白色为背景的连续黑色块二维码图像解析而设计,也更适合用来解析具有严重阴影和渐变的二维码图像。///
    和官方的介绍大致一样。然而目前的大部分二维码都是黑色二维码,白色背景的。不管是二维码扫描还是二维码图像识别,使用GlobalHistogramBinarizer算法的效果要稍微比HybridBinarizer好一些,识别的速度更快,对低分辨的图像识别精度更高。
    然而Demo中默认的是采用HybridBinarizer,我们将其替换成GlobalHistogramBinarizer算法

还有其他优化等等。。。。,但是做完之后发现并没有什么改变,我只能说如果你扫描的角度对了,是和二维码平行的话,二维码绝对识别的出来,而且特别快,如果你不是平行,你贴着屏幕扫二维码都还是扫不出来,最烦的是网上基本没有解决的办法,那些说优化过的Demo角度问题还是没有解决,所以我就去找了AndroidZbar的Demo

Zbar

网上基本都是说Android用Zxing,ios用Zbar,所以我开始没想在Android用Zbar,网上AndroidZbar Demo特别少,然后我就去了OSChina找,发现了github上的一个基于Zbar的开源库BGAQRCode

代码结构:

Paste_Image.png

主要用到的东西:

MainActivity.java

其实就是跳转界面

TestScanActivity

     public class TestScanActivity extends AppCompatActivity implements QRCodeView.Delegate {
    private static final String TAG = TestScanActivity.class.getSimpleName();

    private QRCodeView mQRCodeView;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_scan);
        setSupportActionBar((Toolbar) findViewById(R.id.toolbar));

        mQRCodeView = (ZBarView) findViewById(R.id.zbarview);
        mQRCodeView.setDelegate(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mQRCodeView.startCamera();
    }

    @Override
    protected void onStop() {
        mQRCodeView.stopCamera();
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        mQRCodeView.onDestroy();
        super.onDestroy();
    }
    private void vibrate() {
        Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        vibrator.vibrate(200);
    }
//下面这个方法就是返回扫描结果的
    @Override
    public void onScanQRCodeSuccess(String result) {
        Log.i(TAG, "result:" + result);
        Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
        vibrate();
        mQRCodeView.startSpot();
    }

    @Override
    public void onScanQRCodeOpenCameraError() {
        Log.e(TAG, "打开相机出错");
    }

    public void onClick(View v) {
        switch (v.getId()) {
//开启扫描
            case R.id.start_spot:
                mQRCodeView.startSpot();
                break;
//关闭扫描
            case R.id.stop_spot:
                mQRCodeView.stopSpot();
                break;
            case R.id.start_spot_showrect:
                mQRCodeView.startSpotAndShowRect();
                break;
            case R.id.stop_spot_hiddenrect:
                mQRCodeView.stopSpotAndHiddenRect();
                break;
            case R.id.show_rect:
                mQRCodeView.showScanRect();
                break;
            case R.id.hidden_rect:
                mQRCodeView.hiddenScanRect();
                break;
            case R.id.start_preview:
                mQRCodeView.startCamera();
                break;
            case R.id.stop_preview:
                mQRCodeView.stopCamera();
                break;
            case R.id.open_flashlight:
                mQRCodeView.openFlashlight();
                break;
            case R.id.close_flashlight:
                mQRCodeView.closeFlashlight();
                break;
            case R.id.scan_barcode:
                mQRCodeView.changeToScanBarcodeStyle();
                break;
            case R.id.scan_qrcode:
                mQRCodeView.changeToScanQRCodeStyle();
                break;
        }
    }    ```
###R.layout.activity_test_scan

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/MatchMatch">

<cn.bingoogolapple.qrcode.zbar.ZBarView
    android:id="@+id/zbarview"
    style="@style/MatchMatch"
    app:qrcv_animTime="1000"
    app:qrcv_barCodeTipText="将条码放入框内,即可自动扫描"
    app:qrcv_barcodeRectHeight="140dp"
    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="@mipmap/custom_grid_scan_line"
    app:qrcv_isBarcode="false"
    app:qrcv_isOnlyDecodeScanBoxArea="false"
    app:qrcv_isShowDefaultGridScanLineDrawable="true"
    app:qrcv_isShowDefaultScanLineDrawable="true"
    app:qrcv_isShowTipBackground="true"
    app:qrcv_isShowTipTextAsSingleLine="false"
    app:qrcv_isTipTextBelowRect="false"
    app:qrcv_maskColor="#33FFFFFF"
    app:qrcv_qrCodeTipText="将二维码/条码放入框内,即可自动扫描"
    app:qrcv_rectWidth="200dp"
    app:qrcv_scanLineColor="@color/colorPrimaryDark"
    app:qrcv_toolbarHeight="56dp"
    app:qrcv_topOffset="90dp" />
<include layout="@layout/toolbar"/>
<include layout="@layout/view_control"/>

</RelativeLayout>```

基本只要改这上边两个类,代码比zxing简单N倍,扫描速度也够快是zxing的3~5倍(我觉得用zxing的公司可能做了大量代码算法优化),毕竟Zbar基于c,对于单纯的对扫描速度的有要求,就算我们们不优化代码,也满足我们的需要

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容