什么是二维码:
二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。
现在二维码在我们生活中到处可见,各种APP的开发当然少不了二维码,那么下面我来简绍下二维码的使用.
对于二维码扫描我们使用的是google的开源框架Zxing,我们可以去http://code.google.com/p/zxing/下载源码和Jar包
首先将源码和jar包导入我们的项目中,结构如下:
这里我们需要在功能清单里进行一系列的权限注册
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hsj.example.zxingscannerdemo03">
<span style="color:#ff0000;"> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" /></span>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<span style="color:#ff6666;"><!--捕捉Activity -->
<activity android:name="com.zxing.activity.CaptureActivity"/></span>
</application>
</manifest>
这里我写了一个小案例来实现二维码的功能
主布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<Button
android:id="@+id/button_scanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="68dp"
android:layout_marginStart="68dp"
android:text="扫一扫解二维码" />
<EditText
android:id="@+id/editText_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button_scanner"
android:textSize="10sp"
android:hint="请输入要生成二维码需要的字符串信息" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="生成二维码"
android:id="@+id/button_generator"
android:layout_below="@+id/editText_info"
android:layout_alignLeft="@+id/button_scanner"
android:layout_alignStart="@+id/button_scanner" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView_QuickResponseCode"
android:layout_below="@+id/button_generator"
android:layout_alignLeft="@+id/button_generator"
android:layout_alignStart="@+id/button_generator"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
然后mainActivity
public class MainActivity extends AppCompatActivity {
private Button button_scanner;
private EditText editText_info;
private Button button_generator;
private ImageView imageView_QuickResponseCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.initView();
this.button_scanner.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent,100);
}
});
this.button_generator.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content=editText_info.getText().toString();
if(TextUtils.isEmpty(content)){
editText_info.setError("生成二维码的内容不能为空!");
editText_info.requestFocus();
return;
}
//Bitmap bitmap=getQRCode(content,300);
// Bitmap bitmap=generateQRCode(content,300, BitmapFactory.decodeResource(getResources(),R.mipmap.logo),20);
// imageView_QuickResponseCode.setImageBitmap(bitmap);
//注意:如果中心图片太大,需要设置生成的二维码更大些,否则识别不了
Bitmap bmp01 = getQRCode(editText_info.getText().toString(), 500);
Bitmap bmp02 = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
imageView_QuickResponseCode.setImageBitmap(getBmp(bmp01,bmp02));
}
});
}
/**
* 合成带头像的二维码
* @param bmp01:二维码的bitmap
* @param bmp02:头像的bitmap
*/
public Bitmap getBmp(Bitmap bmp01, Bitmap bmp02) {
if (bmp01 == null) {
return null;
}
int w1 = bmp01.getWidth();
int h1 = bmp01.getHeight();
int w2 = bmp02.getWidth();
int h2 = bmp02.getHeight();
//圈定一个区域(bmp01的区域)
Canvas canvas = new Canvas(bmp01);
//先画出bmp01
canvas.drawBitmap(bmp01, 0, 0, null);
//再画出bmp02(bmp02,画在bmp01的中间)
canvas.drawBitmap(bmp02, w1 / 2 - w2 / 2, h1 / 2 - h2 / 2, null);
//保存
canvas.save(Canvas.ALL_SAVE_FLAG);
//恢复到原来的状态
canvas.restore();
return bmp01;
}
/**
* 根据指定的内容和指定的宽和高生成二维码
* @param str 生成二维码的信息
* @param wAndH 二维码图片的宽和高
* @return 生成的二维码图片
*/
private Bitmap getQRCode(String str, int wAndH) {
//构建生成二维码的对象
MultiFormatWriter formatWriter = new MultiFormatWriter();
Map<EncodeHintType, Object> map = new HashMap<>();
//设置生成二维码的编码字符类型
map.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
//调用其中encode方法生成的位图矩阵BitMatrix
/**
* 参数1:生成二维码需要的字符串信息
* 参数2:生成码的格式(条形码,一维码,二维码)
* 参数3:生成位图矩阵的宽
* 参数4:生成位图矩阵的高
* 参数5:对生成二维码过程的一些配置Map
*/
//把字符串信息转换成位图矩阵
BitMatrix bitMatrix = formatWriter.encode(str, BarcodeFormat.QR_CODE, wAndH, wAndH, map);
int[] p = new int[wAndH * wAndH];
//把位图矩阵转化成一维数组(存储颜色信息)
//外层控制行数
for (int i = 0; i < wAndH; i++) {
//j控制列数
for (int j = 0; j < wAndH; j++) {
//说明在i行j列上有值
if (bitMatrix.get(i, j)) {
//表示有值
p[i * wAndH + j] = Color.BLACK;
} else {
//表示为空
p[i * wAndH + j] = Color.WHITE;
}
}
}
//把颜色只变成像素点填充为图片Bitmap
//先创建一个空的bitmap(宽和高,Config)
Bitmap bmp = Bitmap.createBitmap(wAndH, wAndH, Bitmap.Config.ARGB_8888);
//把颜色值当作像素点填到Bitmap
/**
* 参数1:把一维数组存储的值写入到Bitmap
* 参数2:从一维数组中读取的第一个像素值的索引或者下标
* 参数3:宽度
* 参数4:写入图片的第一个像素点的x坐标
* 参数5:写入图片的第一个像素点的y坐标
* 参数6:宽度
* 参数7:高度
*/
bmp.setPixels(p, 0, wAndH, 0, 0, wAndH, wAndH);
return bmp;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
/**
* 生成中心带有logo的二维码
* @param text 需要生成二维码的内容
* @param widthAndHeight 生成二维码图片的宽和高
* @param mBitmap 中心logo 图片
* @param imgWAndH 中心logo 图片的宽和高,这个值不能太大,否则不识别,一般建议小于20即可
* @return 生成二维码的图片
*/
public Bitmap generateQRCode(String text, int widthAndHeight, Bitmap mBitmap, int imgWAndH) {
Matrix m = new Matrix();
float sx = (float) 2 * imgWAndH / mBitmap.getWidth();
float sy = (float) 2 * imgWAndH / mBitmap.getHeight();
m.setScale(sx, sy);//设置缩放信息
//将logo图片按martix设置的信息缩放
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
mBitmap.getWidth(), mBitmap.getHeight(), m, true);
//imageView.setBackgroundDrawable(new BitmapDrawable(mBitmap));
Hashtable<EncodeHintType, Object> hashtable = new Hashtable<>();
hashtable.put(EncodeHintType.CHARACTER_SET, "utf-8");
hashtable.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
try {
BitMatrix bitMatrix = new MultiFormatWriter()
.encode(editText_info.getText().toString(), BarcodeFormat.QR_CODE,
widthAndHeight, widthAndHeight);
int[] pixles = new int[widthAndHeight * widthAndHeight];
int halfW = widthAndHeight / 2;
int halfH = widthAndHeight / 2;
//控制行数
for (int i = 0; i < widthAndHeight; i++) {
//控制列数
for (int j = 0; j < widthAndHeight; j++) {
if (i > halfW - imgWAndH && i < halfW + imgWAndH
&& j > halfH - imgWAndH
&& j < halfH + imgWAndH) {//该位置用于存放图片信息
//记录图片每个像素信息
pixles[i * widthAndHeight + j] = mBitmap.getPixel
(j - halfH + imgWAndH,
i - halfW + imgWAndH);
} else {
if (bitMatrix.get(i, j)) {//如果有黑块点,记录信息
pixles[i * widthAndHeight + j] = Color.BLACK;//记录黑块信息
}
}
}
}
Bitmap bmp1 = Bitmap.createBitmap(widthAndHeight, widthAndHeight, Bitmap.Config.ARGB_8888);
bmp1.setPixels(pixles, 0, widthAndHeight, 0, 0, widthAndHeight, widthAndHeight);
return bmp1;
} catch (Exception e) {
e.getMessage();
}
return null;
}
private void initView() {
this.button_scanner= (Button) this.findViewById(R.id.button_scanner);
this.editText_info= (EditText) this.findViewById(R.id.editText_info);
this.button_generator= (Button) this.findViewById(R.id.button_generator);
this.imageView_QuickResponseCode= (ImageView) this.findViewById(R.id.imageView_QuickResponseCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==100){
if(resultCode==RESULT_OK){
if(data!=null){
String result=data.getStringExtra("result");
Toast.makeText(this, "扫描结果为:"+result, Toast.LENGTH_SHORT).show();
System.out.println("result="+result);
}
}
}
}
}
看看运行的效果:
当我们点击扫一扫解二维码时就可以打开手机的相机,
我们可以在本文框里输入内容,然后点击生成二维码,就可以将我们输入的内容变成二维码
这样就完成是二维码的基本操作了,你们可以用微信扫一下,是不是很简单!