一个Android平台更快更简单更精准的条形码及二维码解析框架。采用ZBar解析图像数据,兼容Android4.0 (API14)
及以上版本。GitHub地址
最近更新
- V1.1.7
- 修复armeabi架构无法识别二维码的问题。
-
OldCameraScanner
和NewCameraScanner
取消单例模式,增加单例信号量CameraLock
解决可能产生的相机并发操作。 -
CameraScanner
新增enableBrightnessFeedback(boolean enable)
接口,设置是否开启亮度回馈。 -
CameraListener
新增cameraBrightnessChanged(int brightness)
接口,对亮度变化进行回馈。 -
GraphicDecoder
新增setCodeTypes(int[] codeType)
接口指定识别的类型。 -
MaskConstraintLayout
及MaskRelativeLayout
新增frame_viewid
属性,用于指定绘制阴影的View(便于开发者使用自定义的扫描框)。 -
ZBarDecoder
构造方法调整。 -
CameraScanner
中的setSurfaceTexture(SurfaceTexture surfaceTexture)
接口更名为setPreviewTexture(SurfaceTexture surfaceTexture)
,便于理解。 - 移除
BaseHandler
。
目录
- 示例demo
- 功能介绍
- UML类图
- 集成方式
- 使用方式
- 更新计划
- 版本记录
- 关于作者
示例demo
Demo下载 | 示例效果 |
---|---|
点此下载(1.7MB) 或扫描下面二维码 |
|
功能介绍
本项目基于ZBar进行开发,分别对视图、相机、解码三个方面进行了封装,同时降低三者之间的耦合,增加可灵活配置性。
-
视图
- 自定义
AdjustTextureView
,继承自TextureView
,开放setImageFrameMatrix
接口,可根据自身尺寸、图像帧宽高及旋转角度对图像进行校正,解决预览画面变形等异常问题。 - 自定义
ScannerFrameView
,继承自View
,可通过xml属性或接口自定义扫描框、四个角及扫描线的尺寸、颜色、动画等,具体属性使用参考源码注解。 - 自定义
MaskRelativeLayout
&MaskConstraintLayout
,分别继承自RelativeLayout
&ConstraintLayout
,用于绘制扫描框外部阴影。
- 自定义
-
相机
- 兼容
android.hardware.camera2
及android.hardware.Camera
两版API。 - 子线程开启camera,防止阻塞主线程造成界面跳转卡顿。
- 采用单例信号量控制,防止多个实例同时操作相机设备引发异常。
*加入亮度回馈,可智能提示开启闪光灯。 - 开放扫码框Rect设置接口,根据预览尺寸、图像帧尺寸、预览方向计算出扫码框在图像帧上的实际位置,以指定图像识别区域。
- 用
TextureReader
代替ImageReader
,采用openGL绘制图像纹理,主要解决ImageReader
实时输出YUV格式图像时预览掉帧严重的问题。
- 兼容
-
解码
- 支持指定图像区域识别。
- 开放条码类型配置接口,可任意指定需要识别的条码类型。
- 解码回调结果包含条码类型、条码精度,可配置脏数据过滤规则。
UML类图
集成方式
在module的build.gradle
中添加如下代码
dependencies {
implementation 'cn.simonlee.xcodescanner:zbar:1.1.7'
}
使用方式
-
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.7
2018/08/07
- 修复armeabi架构无法识别二维码的问题。
- 增加亮度反馈,可实现提示开启闪光灯功能。
-
CameraScanner
取消单例模式,增加单例信号量CameraLock
解决可能产生的相机并发操作。 -
GraphicDecoder
新增setCodeTypes
接口指定识别的类型。 -
MaskConstraintLayout
及MaskRelativeLayout
新增frame_viewid
属性,用于指定绘制阴影的View(便于开发者使用自定义的扫描框)。 - demo界面调整。
- 发布开源库:
cn.simonlee.xcodescanner:zbar:1.1.7
。
补充:
-
ZBarDecoder
构造方法调整。 -
CameraScanner
中的setSurfaceTexture(SurfaceTexture surfaceTexture)
接口更名为setPreviewTexture(SurfaceTexture surfaceTexture)
,便于理解。 -
CameraScanner
新增enableBrightnessFeedback(boolean enable)
接口,设置是否开启亮度回馈。 -
CameraListener
新增cameraBrightnessChanged(int brightness)
接口,对亮度变化进行回馈。 - 移除
BaseHandler
。
-
V1.1.6
2018/05/08
-
GraphicDecoder
增加本地图片识别接口。 - 废弃
GraphicDecoder.DecodeListener
中的decodeSuccess
回调,改为decodeComplete
。 -
CameraScanner
新增闪光灯控制接口。 - 解决
AdjustTextureView
尺寸变化导致图像显示异常的问题。 - 发布开源库:
cn.simonlee.xcodescanner:zbar:1.1.6
。
-
-
V1.1.5
2018/05/01
- 解决申请权限闪退的问题。
- 解决魅族MX5闪退的问题。
- 修改
ZBarDecoder
和TextureReader
的实现方式,降低CPU占用。 - 暂停/延时解码接口从
CameraScanner
迁移到GraphicDecoder
,CameraScanner
可能因为异步导致暂停后继续回调decodeSuccess
接口。 - 发布开源库:
cn.simonlee.xcodescanner:zbar:1.1.5
。
-
V1.1.4
2018/04/26
- 解决Android4.2退出时闪退的问题。
- 解决某些低端机型可能预览严重丢帧的问题。
- 解决
OldCameraScanner
默认没有开启解码的问题。 - 发布开源库:
cn.simonlee.xcodescanner:zbar:1.1.4
。
-
V1.1.3
2018/04/25
- 修复部分x86设备闪退的问题。
-
CameraScanner
新增stopDecode()
和startDecode(int delay)
接口,可暂停/延时解码。 - ZBar包名由
com.simonlee.xcodescanner
变更为cn.simonlee.xcodescanner
。 - 发布开源库:
cn.simonlee.xcodescanner:zbar:1.1.3
。
-
V1.1.2
2018/04/24
- 修复
ZBarDecoder
中设置解码格式无效的问题。
- 修复
-
V1.1.1
2018/04/16
-
ScannerFrameView
增加高占比属性,可设置相对父容器高的占比。
-
-
V1.1.0
2018/04/16
- 重写
ZBarDecoder
,解决单线程池可能引起的条码解析延迟问题。 - 解决
OldCameraScanner
扫描框区域识别异常的问题。
- 重写
-
V1.0.9
2018/04/14
- 解决
NewCameraScanner
扫描框区域识别异常的问题。 - 解决连续快速旋转屏幕时
NewCameraScanner
出现异常的问题。
- 解决
-
V1.0.8
2018/04/13
-
AutoFixTextureView
更名为AdjustTextureView
,重写图像校正方式。 -
Camera2Scanner
更名为NewCameraScanner
。 - 新增
OldCameraScanner
实现对Android5.0
以下的支持。 - 下调minSdkVersion至14。
- 解决前后台切换,横竖屏切换可能产生的异常。
-
NewCameraScanner
中取消ImageReader
的支持。
-
-
V1.0.7
2018/04/10
- 调整扫描框宽高计算方式,新增
MaskConstraintLayout
布局。 - 优化
Camera2Scanner
,解决后台切换导致的闪退问题。
- 调整扫描框宽高计算方式,新增
-
V1.0.6
2018/04/09
- 调整代码结构,将扫码核心从app移植到zbar中。
-
V1.0.5
2018/03/29
- 增加帧数据的最大尺寸限制,避免因过高像素导致ZBar解析二维码失败。
- 屏蔽ZBar对DataBar(RSS-14)类型条码的支持,此类型实用性不高,且易产生误判。
-
V1.0.4
2018/03/27
- 修改
ZBarDecoder
,修复多线程可能的空指针异常。 - 修改
GraphicDecoder
,EGL14替换EGL10,解决部分机型不兼容的问题;解决多线程可能的空指针异常。
- 修改
-
V1.0.3
2018/03/23
- 新增
TextureReader
,通过双缓冲纹理获取帧数据进行回调,代替ImageReader的使用。 - 修改
GraphicDecoder
,handler放到子类中去操作。
- 新增
-
V1.0.2
2018/03/14
- 新增抽象类
GraphicDecoder
,将条码解析模块进行抽离。 - 新增
ZBarDecoder
,采用ZBar解析条码,并增加解析类型及解析精度设置。 - 修改
ScannerFrameView
,扫描线动画由属性动画实现。 - 修改
Camera2Scanner
,修复释放相机可能导致的异常,增加扫描框区域设置。 - 其他微调。
- 新增抽象类
-
V1.0.1
2018/02/09
- 新增
ScannerFrameLayout
,为RelativeLayout
的子类,可对扫描框的位置和大小进行设置。 - 修改
ScannerFrameView
,可对扫描框内部进行定制。
- 新增
V1.0.0
2018/02/03
初次提交代码。
关于作者
这是我个人的第一个开源项目,在开源的过程中碰到了许多疑点难点,多处借鉴很多大神的成果。因为自己的疏忽没有预先做好参考记录,在这里向那些为开源默默奉献的大神们致敬!Thanks!
如果在使用过程中遇到了闪退、黑屏、无法识别、无法对焦、预览掉帧、内存泄漏等任何异常问题,欢迎提Issues!同时请尽量附上设备型号、android版本号、BUG复现步骤、异常日志、无法识别的图像等,我会尽快安排解决。(若回复不及时可直接微信)
如果您觉得有用,请动动小手给我一个Star来点鼓励吧
Author | GitHub | ||
---|---|---|---|
Simon Lee | [email protected] | XCodeScanner |