二维码背景和意义
二维码作为一种全新的信息存储、传递和识别技术,自诞生之日起就得到了世界上许多国家的关注。它是当代人获取信息重要方式,特别是手持设备上信息的获取。随着时代的发展,它将渗透到我们日常生活的方方面面。现代社会, 人人都接触到二维码,这正反映了时代文化的变迁。充分利用二维码这一技术将会给我们的生活带来极大的便利。
研究现状
国外对二维码技术的研究始于20世纪80年代末,在二维码符号表示技术研究方面已研制出多种码制,在二维码标准化研究方面,国际自动识别制造商协会(AIM)、美国标准化协会(ANSI)已完成了PDF417、QR Code、Code 49、Code 16K、Code One等码制的符号标准。我国对二维码技术的研究相对落后,大约始于1994年。
应用前景
信息获取(名片、地图、WIFI密码、资料)
网站跳转(跳转到微博、手机网站、网站)
广告推送(浏览商家推送的视频、音频广告)
手机电商(手机直接购物下单)
优惠促销(下载电子优惠券,抽奖)
会员管理(获取电子会员信息、VIP服务)
手机支付(扫描商品二维码,通过银行或第三方支付提供的手机端通道完成支付)
研究重点
我们之所以对二维码进行扫描能读出那么多信息,就是因为这些信息被编入了二维码之中。其中QR码具有数据容量大,编码范围广,可靠性高,成本低,纠错力强等优点,现在常见的二维码都是以QR码作为编码的码制。
QR码理论
QR码由两大部分组成:编码区格式和功能图形区。
编码区格式包括了由格式信息、版本信息以及数据信息和 Rs生成的纠错码字,其中大部分是数据信息和纠错码字;
功能图形区是指符号中用于符号定位与特征识别的特定图形,由位置探测图形、分隔符、定位图形以及校正图形组成。
QR码符号区域被空白区包围, 空白区不打印任何信息,四周空白区的宽度为四个模块的究度。
QR码编码
●数据分析:区分数字,字母汉字等,对不同数据模式进行高效编码。
●数据编码:根据数据编码模式将数据字符转化为二进制位流,位流分为每8位一个码字,必要时需加入填充。
●纠错编码:将码字序列分块,生成相应的纠错码字。一并加入对应数据码字后面。采用Reed.Solomom错误控制码实现纠错。
●编码构造:将纠错码字添加到数据码字后面形成最终位流序列。
●模块构造:将寻像图形,分隔符,定位图形,校正图形,码字图统一编 入同一矩阵,每8位码字按2个模块宽度从右下角开始进行蛇形排列。
●加入掩膜:避免出现相似区域,对符号进行异或操作后计分,选择得分最低图形。
●版本与格式:格式信息右5个数据位和10个纠错位组成与掩模图形进行异或运算后填入相应位置。
使用方式
集成默认的二维码扫描页面
在module的build.gradle中执行compile操作
compile 'cn.yipianfengye.android:zxing-library:2.2'
在demo Application中执行初始化操作
@Override
public void onCreate() {
super.onCreate();
ZXingLibrary.initDisplayOpinion(this);
}
在代码中执行打开扫描二维码界面操作
/**
* 打开默认二维码扫描界面
*/
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,CaptureActivity.class);
startActivityForResult(intent, REQUEST_CODE);
}
});
这里的REQUEST_CODE是我们定义的int型常量。
在Activity的onActivityResult方法中接收扫描结果
/**
* 处理二维码扫描结果
*/
if (requestCode == REQUEST_CODE) {
//处理扫描结果(在界面上显示)
If (null != data) {
Bundle bundle = data.getExtras();
if (bundle == null) {
return;
}
If (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
String result = bundle.getString(CodeUtils.RESULT_STRING);
Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
}
}
集成对二维码图片的解析功能
调用系统API打开图库
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
在Activity的onActivityResult方法中获取用户选中的图片并调用二维码图片解析API
if (requestCode == REQUEST_IMAGE) {
if (data != null) {
Uri uri = data.getData();
ContentResolver cr = getContentResolver();
try {
Bitmap mBitmap = MediaStore.Images.Media.getBitmap(cr, uri);//显得到bitmap图片
CodeUtils.analyzeBitmap(mBitmap, new CodeUtils.AnalyzeCallback() {
@Override
public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
Toast.makeText(MainActivity.this, "解析结果:" + result, Toast.LENGTH_LONG).show();
}
@Override
public void onAnalyzeFailed() {
Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
});
if (mBitmap != null) {
mBitmap.recycle();
}
} catch (Exception e) {
e.printStackTrace();
}
}
生成二维码图片
生成带Logo的二维码图片:
/**
* 生成二维码图片
*/
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textContent = editText.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
editText.setText("");
mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
imageView.setImageBitmap(mBitmap);
}
});
生成不带logo的二维码图片
/**
* 生成不带logo的二维码图片
*/
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textContent = editText.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
editText.setText("");
mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
imageView.setImageBitmap(mBitmap);
}
});
支持控制闪光灯
/**
* 打开闪光灯
*/
CodeUtils.isLightEnable(true);
/**
* 关闭闪光灯
*/
CodeUtils.isLightEnable(false);
二维码的生成原理
用特定的集合图形按编排规律在二维方向上发布,采用黑白相间的图形来记录数据符号信息,用数字”0”和”1”作为代码,利用计算机内部逻辑使计算机识别,同时使用若干个与二进制相对应的几何形体表示文字数值信息,白色块表示的就是二进制的”0”,黑块就是”1”.
在QR码上不同的区域则表示着不同的信息
安静区域:空白边框,可以将代码与其他打印信息隔离(例如,在脏信封上,报纸的黑白打印或污迹产品包装上)。
Finder模式:三个角落中的大黑色和白色方块可以很容易地确认这是一个QR码。由于它们只有三个,所以很明显代码的哪个方向以及它指向的角度(除非代码在某种程度上被部分遮挡或损坏)。
对齐模式:这确保代码可以被破译,即使它是扭曲的(以某个角度查看,打印在曲面上,等等)。
定时模式:在三个取景器模式之间水平和垂直地运行,由交替的黑色和白色方块组成。时序模式可以轻松识别QR码中的各个数据单元,在代码损坏或失真时尤其有用。
版本信息:QR码标准有各种不同版本;版本信息(位于两个取景器模式附近)简单地识别在特定代码中使用哪一个。
数据单元:每个单独的黑色或白色方块不属于标准特征之一(时序,对齐和其他模式),包含代码中的一些实际数据。