android 扫描二维码
关于二维码的了解
我们现在常用的二维码为QR码作为编码的码制,他是在一个矩形空间内通过黑、白像素在矩阵中的不同分布来进行编码的。我们知道电脑是使用二进制数字来储存和处理数据的,而在二维码中,用黑白矩阵来表示二进制数据,而我们肉眼看到的黑色表示的是二进制“1”,白色表示的是二进制“0”,黑白的排列组合确定了矩阵式二维码的内容,以便计算机对二维码符合进行编码和分析。通过黑白表示1和0这就是为什么二维码都是黑白图形的原因。
二维码扫描定位流程:首先手机拍照,拍到的照片是彩色的,对于扫描的二维码也是一样,他默认也是彩色的,只不过颜色有深浅之分,所以识别软件正式依靠颜色的深浅来完成对二维码识别的第一步
- 第一步叫做灰度化,也就是说颜色深的按深灰处理,颜色浅的按浅灰处理,
仅仅有了灰度还是不够的,因为扫描还受周围的环境的影响,会有噪点,所以 - 第二部就是去噪。
完成了上面的两部,就进入了至关重要的二值化流程,上面已经说过计算机采用二进制,而将深度和浅度灰阶的图案转换成只有黑色和白色两种颜色,也就是二值化处理的任务。在二值化处理时,二维码将会首先被解读成白色黑色的条码。然后根据解析公式和阈值运算将其转化成二进制信息,也许再深入讲解公式可能一般人不能理解,但是我们要知道,二值化是一个非常复杂而且需要相当准确的步骤。 - 结束了上面步骤后再就是 寻找探测图形? 也就是找到二维码的位置,经常看二维码的朋友都知道,二维码上有三个方块,这三个方块有什么作用?代表了怎样的含义呢?其实它的准确叫法就是位置探测图形。有了这三个点,不管是从哪个方向读取二维码,信息都可以被识别。即使将二维码图形旋转,也可以识别。它的作用主要是方便识别和决定二维码符号中模块的坐标,当得到了一个可识别的二维码后,接下来的工作就是译码和纠错。
- 译码就是对二维码中所包含的格式信息、版本信息、数据和纠错码信息进行解码和比对,而纠错是在译码的同时进行的。其实,一个二维码除了上面讲到的探测图形外,还有各种译码信息被集成在二维码中,通过二维码包含信息示意图我们就可以对一个二维码所含的信息元素有大概的了解。完成了译码,手机上从二维码的识别到解码的工作就完成了。
说到二维码扫描 那就肯定是少不了 ZXing 库的使用了,zxing是由google开发的开源二维码扫描库,支持条形码和二维码的扫描,git 地址为:zxing github地址。
android库组成:
- core : 图片解码的核心内容和测试代码。
- javase: javaSE-special 客户端代码
- android: android客户端扫描代码
- androidtest:android测试app和ZXing 测试代码。
- android-integration: 支持通过intent 启动二维码的扫描。
- android-core:android 相关代码的共享
- glass:简单的谷歌 glass app。
zxing还 提供了ios 和 java等客户端的支持。
cpp
C++ port
iphone
iPhone client
objc
Objective C port
actionscript
Partial ActionScript port
jruby
JRuby wrapper
基于ZXing的第三方库
这个使用启动来要简单一点,
库的地址为:https://github.com/journeyapps/zxing-android-embedded
如何使用这个库
只需要在build.gradle 文件中添加如下内容:
repositories{
jcenter()
}
dependencies{
compile 'com.journeyapps:zxing-android-embedded:3.0.2@aar'
compile 'com.google.zxing:core:3.2.0'
}
然后更新gradle,就会自动导入库了
导入完后使用:
//Activity中使用
new IntentIntegrator(this).initiateScan();
/*fragment中使用*/
IntentIntegrator.forFragment(this).initateScan();
//如果使用的是兼容包中的fragment则使用下面的方法
IntentIntegrator.forSupportFragment.initateScan();
如需要更多的设置可以在:
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES);
integrator.setPrompt("Scan a barcode");
integrator.setCameraId(0);
// Use a specific camera of the deviceintegrator.setBeepEnabel(false);
integrator.setBarcodeImageEnable(true);integrator.initiateScan();
获取扫描到的结果
// Get the results:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
if(result.getContents() == null) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
设置方向:
方向这个问题可以通过 建立一个CaptureActivityAnyOrientation,这个activity集成字CaptureActivity,然后你在manifest中设置这activity的方向,
<activity android:name=".CaptureActivityAnyOrientation"
android:screenOrientation="fullSensor"
android:stateNotNeeded="true"
android:theme="@style/zxing_CaptureTheme"
android:windowSoftInputMode="stateAlwaysHidden"></activity>
通过设置这个capture activity来限制取景界面的方向。
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setCaptureActivity(CaptrueActivityAnyOrientation.class);
integrator.setOrientationLocked(false);
integrator.initiateScan();