您的位置:首页 > 其它

条形码、二维码的生成与扫描、解析本地二维码

2017-11-20 15:11 316 查看
在学习了个大神的笔记后,我跟着弄才实现出来的,但大神的网址链接弄掉了。。。经过我的再次回忆,按着当初搜索的路径,终于找到了原文,特此附上链接Github项目解析(十)–>几行代码快速集成二维码扫描库 - CSDN博客 http://blog.csdn.net/qq_23547831/article/details/52037710
自行添加了条形码的生成功能,图片路径获取代码。

效果图:





**

准备工作

**:

1.添加权限

<!-- 对存储设备的读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 相机 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 振动 -->
<uses-permission android:name="android.permission.VIBRATE" />


2.添加依赖:

compile 'cn.yipianfengye.android:zxing-library:2.2'


准备就绪了,马上开干啦。最开始解析本地含二维码的图片时,获取图片路径总报错,我就把它单独放出来进行测试了,现在当然是没问题啦~

所以首界面的功能就是:二维码的扫描、生成(有无logo)、条形码的生成,解析图片界面的功能就只是解析本地包含二维码的图片而已。说了这么多的废话了,是时候亮家伙了

**

功能

**

1.首页布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/tv_parse_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:layout_gravity="bottom"
android:layout_marginTop="15dp"
android:textColor="@color/colorAccent"
android:text="解析二维码图片"/>
<TextView
android:id="@+id/tv_scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:layout_marginTop="15dp"
android:text="扫描二维码"/>

<TextView
android:id="@+id/tv_parse_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="15dp"
android:paddingLeft="5dp"
android:text="扫描解析结果:"/>
<EditText
android:id="@+id/ed_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:hint="请输入"/>
<TextView
android:id="@+id/tv_make_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:layout_marginTop="15dp"
android:text="生成有logo的二维码"/>
<TextView
android:id="@+id/tv_make_code_no_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:layout_marginTop="15dp"
android:text="生成无logo的二维码"/>
<TextView
android:id="@+id/tv_make_bar_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:layout_marginTop="15dp"
android:text="生成条形码"/>
<ImageView
android:id="@+id/img_code"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>


2.activity代码

我喜欢写很多注释,这样方便自己复习功能时,直接看代码就可以看到很多相关的知识点,但也许这篇的注释并不多,因为不需要啊。

注意,需要先执行初始化操作ZXingLibrary.initDisplayOpinion(this);

/**
* 扫描二维码
* 解析图片二维码
* 根据输入的文字生成有无logo的二维码
* 根据输入的文字生成条形码
*/
public class HomeActivity extends AppCompatActivity {

private TextView tvScan;
private TextView tvParseResult;
private TextView tvMakeCode;
private TextView tvMakeCodeNoLogo;
private TextView tvMakeBarCode;
private EditText edInput;
private ImageView imgCode;
private Bitmap mBitmap;
private TextView tvParseImage;

private static final int REQUEST_CODE = 1001;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);

//初始化
ZXingLibrary.initDisplayOpinion(this);

tvScan = (TextView) this.findViewById(R.id.tv_scan);
tvParseResult  =  (TextView) this.findViewById(R.id.tv_parse_result);
edInput = (EditText) this.findViewById(R.id.ed_input);
tvMakeCode = (TextView) this.findViewById(R.id.tv_make_code);
tvMakeCodeNoLogo = (TextView) this.findViewById(R.id.tv_make_code_no_logo);
tvMakeBarCode = (TextView) this.findViewById(R.id.tv_make_bar_code);
imgCode = (ImageView) this.findViewById(R.id.img_code);
tvParseImage =  (TextView) this.findViewById(R.id.tv_parse_image);

//解析二维码图片
tvParseImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(HomeActivity.this,ActParseImage.class);
startActivity(intent);
}
});

//扫描二维码
tvScan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(HomeActivity.this, CaptureActivity.class);
startActivityForResult(intent, REQUEST_CODE);
}
});

//生成有logo的二维码图片
tvMakeCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String textContent = edInput.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
imgCode.setImageBitmap(mBitmap);
}
});
//生成无logo的二维码图片
tvMakeCodeNoLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String textContent = edInput.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
imgCode.setImageBitmap(mBitmap);
}
});
tvMakeBarCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textContent = edInput.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
makeBarCode(textContent);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case 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);
tvParseResult.setText("扫描解析结果:" + result);
} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
Toast.makeText(HomeActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
}
break;
}
}

/**
* 制作条形码
*/
public void makeBarCode(String barCode){
int size = barCode.length();
for (int i = 0; i < size; i++) {
int c = barCode.charAt(i);
if ((19968 <= c && c < 40623)) {
Toast.makeText(HomeActivity.this, "生成条形码的时刻不能是中文", Toast.LENGTH_SHORT).show();
return;
}
}
Bitmap bmp = null;
try {
if (!TextUtils.isEmpty(barCode)) {
bmp = CreateOneDCode(barCode);
}
} catch (WriterException e) {
e.printStackTrace();
}
if (bmp != null) {
imgCode.setImageBitmap(bmp);
}
}

/**
* 用于将给定的内容生成成一维条码 注:目前生成内容为中文的话将直接报错,要修改底层jar包的内容
*
* @param content 将要生成一维条码的内容
* @return 返回生成好的一维条码bitmap
* @throws WriterException WriterException异常
*/
public Bitmap CreateOneDCode(String content) throws WriterException {
// 生成一维条码,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
int imgWidth = this.getResources().getDisplayMetrics().widthPixels - 40;
int imgHeight = imgWidth / 5 * 2;

BitMatrix matrix = new MultiFormatWriter().encode(content,
BarcodeFormat.CODE_128, imgWidth, imgHeight);
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = 0xff000000;
}
}
}

Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
// 通过像素数组生成bitmap,具体参考api
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
}


3.解析二维码图片布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/tv_parse_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:layout_marginTop="15dp"
android:text="解析二维码图片"/>
<TextView
android:id="@+id/tv_parse_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="15dp"
android:paddingLeft="5dp"
android:text="解析结果:"/>
<ImageView
android:id="@+id/img_code"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>


4.解析二维码图片activity

注意哦,Android6.0及以上不仅要声明权限,还需要在使用的时候,自动询问,此处读取本地图片是必须要进行这样的操作的,但我在这偷了个懒,我没有写自动询问权限,直接去设置里面全部授予了

public class ActParseImage extends AppCompatActivity{

private TextView tvParseImage;
private TextView tvParseResult;
private ImageView imgCode;

private static final int REQUEST_IMAGE = 1102;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_act_parseimage);

//初始化
ZXingLibrary.initDisplayOpinion(this);

tvParseImage =  (TextView) this.findViewById(R.id.tv_parse_image);
tvParseResult  =  (TextView) this.findViewById(R.id.tv_parse_result);
imgCode = (ImageView) this.findViewById(R.id.img_code);

//解析二维码图片
tvParseImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tvParseResult.setText("");
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case REQUEST_IMAGE:
if (data != null) {
String imagePath = "";//获得图片路径
Uri uri = data.getData();
imagePath = getRealPathFromUri(this,uri);
try {
CodeUtils.analyzeBitmap(imagePath, new CodeUtils.AnalyzeCallback() {
@Override
public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
tvParseResult.setText("解析结果:" + result);
imgCode.setImageBitmap(mBitmap);
}

@Override
public void onAnalyzeFailed() {
Toast.makeText(ActParseImage.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
break;
}
}

/**
* 根据Uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri     图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
public static String getRealPathFromUri(Context context, Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
if (sdkVersion >= 19) { // api >= 19
return getRealPathFromUriAboveApi19(context, uri);
} else { // api < 19
return getRealPathFromUriBelowAPI19(context, uri);
}
}

/**
* 适配api19以下(不包括api19),根据uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri     图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
return getDataColumn(context, uri, null, null);
}

/**
* 适配api19及以上,根据uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri     图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
@SuppressLint("NewApi")
private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
String filePath = null;
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document类型的 uri, 则通过document id来进行处理
String documentId = DocumentsContract.getDocumentId(uri);
if (isMediaDocument(uri)) { // MediaProvider
// 使用':'分割
String id = documentId.split(":")[1];

String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = {id};
filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
} else if (isDownloadsDocument(uri)) { // DownloadsProvider
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
filePath = getDataColumn(context, contentUri, null, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())){
// 如果是 content 类型的 Uri
filePath = getDataColumn(context, uri, null, null);
} else if ("file".equals(uri.getScheme())) {
// 如果是 file 类型的 Uri,直接获取图片对应的路径
filePath = uri.getPath();
}
return filePath;
}

/**
* 获取数据库表中的 _data 列,即返回Uri对应的文件路径
* @return
*/
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
String path = null;

String[] projection = new String[]{MediaStore.Images.Media.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
path = cursor.getString(columnIndex);
}
} catch (Exception e) {
if (cursor != null) {
cursor.close();
}
}
return path;
}

/**
* @param uri the Uri to check
* @return Whether the Uri authority is MediaProvider
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}

/**
* @param uri the Uri to check
* @return Whether the Uri authority is DownloadsProvider
*/
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: