Skip to content

A new frame for decode QR code and bar code on Android. It's faster, simpler and more accurate.

License

Notifications You must be signed in to change notification settings

Simon-Leeeeeeeee/XCodeScanner

Repository files navigation

🌟 XCodeScanner

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

English

目录

示例demo

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

功能介绍

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

  • 视图

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

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

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

UML类图

uml

集成方式

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

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

使用方式

  • 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) {
            mCameraScanner = new NewCameraScanner(this);
        } else {
            mCameraScanner = new OldCameraScanner(this);
        }
    }
  • STEP.2

    在onSurfaceTextureAvailable回调中设置SurfaceTexture及TextureView的宽高,然后开启相机

    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mCameraScanner.setPreviewTexture(surface);
        mCameraScanner.setPreviewSize(width, height);
        mCameraScanner.openCamera(this);
    }
  • 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(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();
    }

注意事项

  • Tips.1

    在Activity的onPause方法中关闭相机

    public void onPause() {
        mCameraScanner.closeCamera();
        super.onPause();
    }
  • Tips.2

    在Activity的onRestart方法中开启相机

    public void onRestart() {
        //部分机型在后台转前台时会回调onSurfaceTextureAvailable开启相机,因此要做判断防止重复开启
        if (mTextureView.isAvailable()) {
            mCameraScanner.setPreviewTexture(mTextureView.getSurfaceTexture());
            mCameraScanner.setPreviewSize(mTextureView.getWidth(), mTextureView.getHeight());
            mCameraScanner.openCamera(this.getApplicationContext());
        }
        super.onRestart();
    }
  • Tips.3

    设置扫码框识别区域时,要考虑到扫码框的margin和padding属性。

更新计划

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

版本记录

  • V1.1.10 2018/09/21

    1. 修复OldCameraScanner中判断闪光灯状态时可能引起的空指针异常。
    2. 亮度回馈由每20帧回调一次平均值改为每帧进行回调。
    3. 依赖版本更新:cn.simonlee.xcodescanner:zbar:1.1.10
  • V1.1.9 2018/09/19

    1. 修复在V1.1.8中NewCameraScanner关闭相机时提前释放SurfaceTexture的问题。
    2. 依赖版本更新:cn.simonlee.xcodescanner:zbar:1.1.9
  • V1.1.8 2018/09/10

    1. ZBarDecoder中在子线程实例化ImageScanner对象,避免在主线程中进行System.loadLibrary()
    2. 修复NewCameraScanner中关闭相机时未释放Surface对象的问题。
    3. 依赖版本更新:cn.simonlee.xcodescanner:zbar:1.1.8
  • V1.1.7 2018/08/07

    1. 修复armeabi架构无法识别二维码的问题。
    2. 增加亮度反馈,可实现提示开启闪光灯功能。
    3. OldCameraScannerNewCameraScanner取消单例模式,增加单例信号量CameraLock解决可能产生的相机并发操作。
    4. GraphicDecoder新增setCodeTypes(int[] codeType)接口指定识别的类型。
    5. MaskConstraintLayoutMaskRelativeLayout新增frame_viewid属性,用于指定绘制阴影的View(便于开发者使用自定义的扫描框)。
    6. ZBarDecoder构造方法调整。
    7. CameraScanner中的setSurfaceTexture(SurfaceTexture surfaceTexture)接口更名为setPreviewTexture(SurfaceTexture surfaceTexture)
    8. CameraScanner新增enableBrightnessFeedback(boolean enable)接口,设置是否开启亮度回馈。
    9. CameraListener新增cameraBrightnessChanged(int brightness)接口,对亮度变化进行回馈。
    10. 移除BaseHandler
    11. 依赖版本更新:cn.simonlee.xcodescanner:zbar:1.1.7
  • 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,由此带来不便的敬请谅解。
  • 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 初次提交代码。

关于作者

这是我个人的第一个开源项目,在开源的过程中碰到了许多疑点难点,多处借鉴很多大神的成果。因为自己的疏忽没有预先做好参考记录,在这里向那些为开源默默奉献的大神们致敬!Thanks!

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

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

Author E-mail 博客 WeChat
Simon Lee jmlixiaomeng@163.com 简书 · 掘金 wechat

About

A new frame for decode QR code and bar code on Android. It's faster, simpler and more accurate.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published