美文网首页Android开发录Android技术文章Android
Android新兴扫码框架:XCodeScanner(持续更新)

Android新兴扫码框架:XCodeScanner(持续更新)

作者: SimonLeeeeeeeee | 来源:发表于2018-04-24 18:53 被阅读1454次

    一个Android平台更快更简单更精准的条形码及二维码解析框架。采用ZBar解析图像数据,兼容Android4.0 (API14)及以上版本。GitHub地址

    目录

    示例demo

    Demo下载 示例效果
    点此下载 或扫描下面二维码
    demo
    gif

    功能介绍

    本项目基于ZBar进行开发,分别对视图、相机、解码三个方面进行了高度封装,同时降低三者之间的耦合,增加可灵活配置性。

    • 视图

      • 自定义AdjustTextureView,继承自TextureView,开放setImageFrameMatrix接口,可根据自身尺寸、图像帧宽高及旋转角度对图像进行校正,解决预览画面变形等异常问题。
      • 自定义ScannerFrameView,继承自View,可通过xml属性或接口自定义扫描框、四个角及扫描线的尺寸、颜色、动画等,具体属性使用参考源码注解
      • 自定义MaskRelativeLayout&MaskConstraintLayout,分别继承自RelativeLayout&ConstraintLayout,做为ScannerFrameView的父容器,用于绘制扫描框外部阴影。
    • 相机

      • 兼容android.hardware.camera2android.hardware.Camera两版API。
      • 子线程开启camera,防止阻塞主线程造成界面跳转卡顿。
      • 采用单例模式,防止出现多个实例同时操作相机设备引发异常。
      • 开放扫码框Rect设置接口,根据预览尺寸、图像帧尺寸、预览方向计算出扫码框在图像帧上的实际位置,以指定图像识别区域。
      • TextureReader代替ImageReader,采用openGL绘制图像纹理,主要解决预览掉帧严重的问题,实时输出YUV格式图像。
    • 解码

      • 支持指定图像区域识别。
      • 开放条码类型配置接口,可任意指定需要识别的条码类型。
      • 解码回调结果包含条码类型、条码精度,可配置脏数据过滤规则。

    UML类图

    uml

    集成方式

    在module的build.gradle中添加如下代码

        dependencies {
            implementation 'cn.simonlee.xcodescanner:zbar:1.1.6'
        }
    

    使用方式

    • STEP.1
      在Activity的onCreate方法中获取CameraScanner实例,并对CameraScanner和TextureView设置监听
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_scan_constraint);
       mTextureView = findViewById(R.id.textureview);
       mTextureView.setSurfaceTextureListener(this);
        /*
        * 注意,SDK21的设备是可以使用NewCameraScanner的,但是可能存在对新API支持不够的情况,比如红米Note3(双网通Android5.0.2)
        * 开发者可自行配置使用规则,比如针对某设备型号过滤,或者针对某SDK版本过滤
        * */
       if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {//此处示例过滤掉了SDK21
          mCameraScanner = OldCameraScanner.getInstance();
       } else {
          mCameraScanner = NewCameraScanner.getInstance();
       }
       mCameraScanner.setCameraListener(this);
    }
    
    • STEP.2
      在onSurfaceTextureAvailable回调中设置SurfaceTexture及TextureView的宽高,然后开启相机
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
       mCameraScanner.setSurfaceTexture(surface);
       mCameraScanner.setPreviewSize(width, height);
       mCameraScanner.openCamera(this.getApplicationContext());
    }
    
    • STEP.3
      在openCameraSuccess回调中设置图像帧的宽高及旋转角度,获取ZBarDecoder实例设置给CameraScanner
    public void openCameraSuccess(int frameWidth, int frameHeight, int frameDegree) {
       mTextureView.setImageFrameMatrix(frameWidth, frameHeight, frameDegree);
       if (mGraphicDecoder == null) {
          mGraphicDecoder = new ZBarDecoder();//使用带参构造方法可指定条码识别的格式
          mGraphicDecoder.setDecodeListener(this);
       }
       //调用setFrameRect方法会对识别区域进行限制,注意getLeft等获取的是相对于父容器左上角的坐标,实际应传入相对于TextureView左上角的坐标。
       mCameraScanner.setFrameRect(mScannerFrameView.getLeft(), mScannerFrameView.getTop(), mScannerFrameView.getRight(), mScannerFrameView.getBottom());
       mCameraScanner.setGraphicDecoder(mZBarDecoder);
    }
    
    • STEP.4
      在ZBarDecoder的decodeSuccess回调中获取解析结果,开发者可根据回传的条码类型及精度自定义脏数据过滤规则
    public void decodeSuccess(int type, int quality, String result) {
       ToastHelper.showToast("[类型" + type + "/精度" + quality + "]" + result, ToastHelper.LENGTH_SHORT);
    }
    
    • STEP.5
      在Activity的onDestroy方法中关闭相机和解码
    public void onDestroy() {
       mCameraScanner.setGraphicDecoder(null);
       mCameraScanner.detach();
       if (mGraphicDecoder != null) {
          mGraphicDecoder.setDecodeListener(null);
          mGraphicDecoder.detach();
       }
       super.onDestroy();
    }
    
    • 注意.1
      在Activity的onPause方法中关闭相机
    public void onPause() {
       mCameraScanner.closeCamera();
       super.onPause();
    }
    
    • 注意.2
      在Activity的onRestart方法中开启相机
    public void onRestart() {
       //部分机型在后台转前台时会回调onSurfaceTextureAvailable开启相机,因此要做判断防止重复开启
       if (mTextureView.isAvailable()) {
          mCameraScanner.setSurfaceTexture(mTextureView.getSurfaceTexture());
          mCameraScanner.setPreviewSize(mTextureView.getWidth(), mTextureView.getHeight());
          mCameraScanner.openCamera(this.getApplicationContext());
       }
       super.onRestart();
    }
    

    更新计划

    • 增加扫描线自定义drawable。
    • 结合OpenCV,提供二维码检测、二维码定位、角度校正、图像滤波等支持,以解决复杂图形的识别问题。
    • 增加环境亮度监测。
    • 增加Zxing支持。
    • 增加二维码生成功能。

    版本记录

    • V1.1.6 2018/05/08

      1. GraphicDecoder增加本地图片识别接口。
      2. 废弃GraphicDecoder.DecodeListener中的decodeSuccess回调,改为decodeComplete
      3. CameraScanner新增闪光灯控制接口。
      4. 解决AdjustTextureView尺寸变化导致图像显示异常的问题。
      5. 发布开源库:cn.simonlee.xcodescanner:zbar:1.1.6
    • V1.1.5 2018/05/01

      1. 解决申请权限闪退的问题。
      2. 解决魅族MX5闪退的问题。
      3. 修改ZBarDecoderTextureReader的实现方式,降低CPU占用。
      4. 新增DebugZBarDecoder,继承自ZBarDecoder,便于示例程序进行兼容性测试。
      5. 暂停/延时解码接口从CameraScanner迁移到GraphicDecoderCameraScanner可能因为异步导致暂停后继续回调decodeSuccess接口。
      6. 发布开源库:cn.simonlee.xcodescanner:zbar:1.1.5
    • V1.1.4 2018/04/26

      1. 解决Android4.2退出时闪退的问题。
      2. 解决某些低端机型可能预览严重丢帧的问题。
      3. 解决OldCameraScanner默认没有开启解码的问题。
      4. 发布开源库:cn.simonlee.xcodescanner:zbar:1.1.4
    • V1.1.3 2018/04/25

      1. 修复部分x86设备闪退的问题。
      2. CameraScanner新增stopDecode()startDecode(int delay)接口,可暂停/延时解码。
      3. ZBar包名由com.simonlee.xcodescanner变更为cn.simonlee.xcodescanner
      4. 发布开源库:cn.simonlee.xcodescanner:zbar:1.1.3codescanner变更为xcodescanner,由此带来不便的敬请谅解。
      5. 有开发者反馈部分机型存在闪退、无法解析二维码的问题,将在近期解决。
    • V1.1.2 2018/04/24

      1. 修复ZBarDecoder中设置解码格式无效的问题。
    • V1.1.1 2018/04/16

      1. ScannerFrameView增加高占比属性,可设置相对父容器高的占比。
      2. 发布开源库:cn.simonlee.codescanner:zbar:1.1.1
    • V1.1.0 2018/04/16

      1. 重写ZBarDecoder,解决单线程池可能引起的条码解析延迟问题。
      2. 解决OldCameraScanner扫描框区域识别异常的问题。
    • V1.0.9 2018/04/14

      1. 解决NewCameraScanner扫描框区域识别异常的问题。
      2. 解决连续快速旋转屏幕时NewCameraScanner出现异常的问题。
    • V1.0.8 2018/04/13

      1. AutoFixTextureView更名为AdjustTextureView,重写图像校正方式。
      2. Camera2Scanner更名为NewCameraScanner
      3. 新增OldCameraScanner实现对Android5.0以下的支持。
      4. 下调minSdkVersion至14。
      5. 解决前后台切换,横竖屏切换可能产生的异常。
      6. NewCameraScanner中取消ImageReader的支持。
    • V1.0.7 2018/04/10

      1. 调整扫描框宽高计算方式,新增MaskConstraintLayout布局。
      2. 优化Camera2Scanner,解决后台切换导致的闪退问题。
    • V1.0.6 2018/04/09

      1. 调整代码结构,将扫码核心从app移植到zbar中。
    • V1.0.5 2018/03/29

      1. 增加帧数据的最大尺寸限制,避免因过高像素导致ZBar解析二维码失败。
      2. 屏蔽ZBar对DataBar(RSS-14)格式条码的支持,此格式实用性不高,且易产生误判。
    • V1.0.4 2018/03/27

      1. 修改ZBarDecoder,修复多线程可能的空指针异常。
      2. 修改GraphicDecoder,EGL14替换EGL10,解决部分机型不兼容的问题;解决多线程可能的空指针异常。
    • V1.0.3 2018/03/23

      1. 新增TextureReader,通过双缓冲纹理获取帧数据进行回调,代替ImageReader的使用。
      2. 修改GraphicDecoder,handler放到子类中去操作。
    • V1.0.2 2018/03/14

      1. 新增抽象类GraphicDecoder,将条码解析模块进行抽离。
      2. 新增ZBarDecoder,采用ZBar解析条码,并增加解析类型及解析精度设置。
      3. 修改ScannerFrameView,扫描线动画由属性动画实现。
      4. 修改Camera2Scanner,修复释放相机可能导致的异常,增加扫描框区域设置。
      5. 其他微调。
    • V1.0.1 2018/02/09

      1. 新增ScannerFrameLayout,为RelativeLayout的子类,可对扫描框的位置和大小进行设置。
      2. 修改ScannerFrameView,可对扫描框内部进行定制。
    • V1.0.0 2018/02/03
      初次提交代码。

    关于作者

    这是我个人的第一个开源项目,慢慢悠悠也投入了不少精力。在开源的过程中碰到了许多疑点难点,其中借鉴了很多大神的成果。在这里向那些为开源默默奉献的大神们致敬!谢谢你们!

    如果在使用过程中遇到了闪退、黑屏、无法识别、无法对焦、预览掉帧、内存泄漏等任何异常问题,欢迎提Issues!同时请尽量附上设备型号、android版本号、BUG复现步骤、异常日志、无法识别的图像等,我会尽快安排解决。

    如果您觉得有用,请动动小手给我一个Star来点鼓励吧

    Author E-mail GitHub WeChat
    Simon Lee jmlixiaomeng@163.com XCodeScanner wechat

    相关文章

      网友评论

      本文标题:Android新兴扫码框架:XCodeScanner(持续更新)

      本文链接:https://www.haomeiwen.com/subject/jozjlftx.html