Android Zxing 相册二维码/条码图片识别
来源:互联网 发布:我要开网络推广公司 编辑:程序博客网 时间:2024/04/28 17:59
Android Zxing相册二维码/条码图片识别
在网上搜了好多例子放到项目中都会有些问题,有的是只能识别二维码图片无法识别条码图片,有的是可以识别条码但是识别率特别低。下面就介绍我整理过后在项目中使用的相册图片二维码条码识别集成步骤。
第一步 添加Zxing依赖
这里只介绍Android Studio中添加依赖的方法。
在app文件夹中build.gradle中的dependencies代码块儿中添加如下配置(ZXing版本根据需要引入):
compile 'com.google.zxing:core:3.2.0'
第二步 跳转相册
在项目中要跳转相册的点击事件中调用次方法,调用此方法后会跳转系统的相册界面,在系统相册界面选择好图片后会走activity的onActivityResult回调方法,并带回选中的图片的Uri。
publicvoid goToPhotoAlbum() { Intent intent = new Intent(Intent.ACTION_PICK, null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); activity.startActivityForResult(intent, IntentConstant.REQUEST_PHOTO_ALBUM); }
第三步 在Activity的onActivityResult中处理Intent
在相册界面选中图片后会走onActivityResult回调方法。在回调方法中获取到intent中图片的Uri,再通过Uri获取到图片的真实路径,获取到路径后就可以识别图片
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // RESULT_OK 为Activity类中的常量,值为-1 if (resultCode == RESULT_OK && requestCode == 11) { String photoPath = getRealFilePath(mContext,data.getData()); if (null == photoPath){ // 路径为null则获取图片失败 Toast.makeText(this, "图片获取失败,请重试", Toast.LENGTH_SHORT).show(); }else { // 解析图片... parsePhoto(photoPath); } } }
通过Uri获取图片路径的方法如下(觉得不好用就从别的地方找吧,能实现功能就行):
@TargetApi(Build.VERSION_CODES.KITKAT) public static String getPath(Context context, Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{ split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } else if ("content".equalsIgnoreCase(uri.getScheme())) { if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; }
第四步 解析二维码/条码图片
parsePhoto方法就是识别图片二维码条码的方法,建议放到异步任务中去可以使用RxJava或者AsyncTask下面分别介绍两种实现方式:
RxJava实现方式:
需要在build.gradle中添加Rxjava和RxAndroid依赖:
//RxJava compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.0.1'
异步操作代码:
在parsePhoto方法中定义被观察者:
public void parsePhoto(final String path){ Observable<String> observable = new Observable<String>() { @Override protected void subscribeActual(Observer<? super String> observer) { // 解析二维码/条码 String result = QRCodeDecoder.syncDecodeQRCode(path); // 要做判空,不然可能会报空指针异常 result = (null == result)?"":result; observer.onNext(result); } }; // RxJava 根据图片路径获取ZXing扫描结果的过程执行在io线程,获取到结果后的操作在主线程 observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer); }
定义观察者:
private Observer<String> observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) {} @Override public void onNext(String value) { if(StringUtils.isEmpty(value)){ Toast.makeText(this, "未识别到二维码/条码", Toast.LENGTH_SHORT).show(); }else { // 识别到二维码/条码内容:value } } @Override public void onError(Throwable e) {} @Override public void onComplete() {} };
AsyncTask实现方式:
public void parsePhoto(final String path){ AsyncTask myTask = new AsyncTask<String, Integer, String>() { @Override protected String doInBackground(String... params) { // 解析二维码/条码 return QRCodeDecoder.syncDecodeQRCode(path); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); if(null == s){ Toast.makeText(activity, "图片获取失败,请重试", Toast.LENGTH_SHORT).show(); }else { // 识别出图片二维码/条码,内容为s } } }.execute(path); }
解析二维码的工具类QRCodeDecoder如下所示:
import android.graphics.Bitmap;import android.graphics.BitmapFactory;import com.google.zxing.BarcodeFormat;import com.google.zxing.BinaryBitmap;import com.google.zxing.DecodeHintType;import com.google.zxing.MultiFormatReader;import com.google.zxing.RGBLuminanceSource;import com.google.zxing.Result;import com.google.zxing.common.GlobalHistogramBinarizer;import com.google.zxing.common.HybridBinarizer;import java.util.ArrayList;import java.util.EnumMap;import java.util.List;import java.util.Map;/** * 描述:解析二维码图片 */public class QRCodeDecoder { public static final Map<DecodeHintType, Object> HINTS = new EnumMap<>(DecodeHintType.class); static { List<BarcodeFormat> allFormats = new ArrayList<>(); allFormats.add(BarcodeFormat.AZTEC); allFormats.add(BarcodeFormat.CODABAR); allFormats.add(BarcodeFormat.CODE_39); allFormats.add(BarcodeFormat.CODE_93); allFormats.add(BarcodeFormat.CODE_128); allFormats.add(BarcodeFormat.DATA_MATRIX); allFormats.add(BarcodeFormat.EAN_8); allFormats.add(BarcodeFormat.EAN_13); allFormats.add(BarcodeFormat.ITF); allFormats.add(BarcodeFormat.MAXICODE); allFormats.add(BarcodeFormat.PDF_417); allFormats.add(BarcodeFormat.QR_CODE); allFormats.add(BarcodeFormat.RSS_14); allFormats.add(BarcodeFormat.RSS_EXPANDED); allFormats.add(BarcodeFormat.UPC_A); allFormats.add(BarcodeFormat.UPC_E); allFormats.add(BarcodeFormat.UPC_EAN_EXTENSION); HINTS.put(DecodeHintType.TRY_HARDER, BarcodeFormat.QR_CODE); HINTS.put(DecodeHintType.POSSIBLE_FORMATS, allFormats); HINTS.put(DecodeHintType.CHARACTER_SET, "utf-8"); } private QRCodeDecoder() { } /** * 同步解析本地图片二维码。该方法是耗时操作,请在子线程中调用。 * * @param picturePath 要解析的二维码图片本地路径 * @return 返回二维码图片里的内容 或 null */ public static String syncDecodeQRCode(String picturePath) { return syncDecodeQRCode(getDecodeAbleBitmap(picturePath)); } /** * 同步解析bitmap二维码。该方法是耗时操作,请在子线程中调用。 * * @param bitmap 要解析的二维码图片 * @return 返回二维码图片里的内容 或 null */ public static String syncDecodeQRCode(Bitmap bitmap) { Result result = null; RGBLuminanceSource source = null; try { int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] pixels = new int[width * height]; bitmap.getPixels(pixels, 0, width, 0, 0, width, height); source = new RGBLuminanceSource(width, height, pixels); result = new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(source)), HINTS); return result.getText(); } catch (Exception e) { e.printStackTrace(); if (source != null) { try { result = new MultiFormatReader().decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)), HINTS); return result.getText(); } catch (Throwable e2) { e2.printStackTrace(); } } return null; } } /** * 将本地图片文件转换成可解码二维码的 Bitmap。为了避免图片太大,这里对图片进行了压缩。感谢 https://github.com/devilsen 提的 PR * * @param picturePath 本地图片文件路径 * @return */ private static Bitmap getDecodeAbleBitmap(String picturePath) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(picturePath, options); int sampleSize = options.outHeight / 400; if (sampleSize <= 0) { sampleSize = 1; } options.inSampleSize = sampleSize; options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(picturePath, options); } catch (Exception e) { return null; } }}
以上就是本人实现的相册图片二维码/条码识别的全部内容,如有错误欢迎指正!
阅读全文
1 0
- Android Zxing 相册二维码/条码图片识别
- Android实现二维码扫描功能(四)-ZXing识别图片二维码,相册选图
- Zxing图片识别 从相册选二维码图片解析总结
- Zxing图片识别 从相册选二维码图片解析总结
- 在Android上使用ZXing识别条码/二维码
- 在Android上使用ZXing识别条码/二维码
- 在Android上使用ZXing识别条码/二维码
- 在Android上使用ZXing识别条码/二维码
- 利用zxing识别图片二维码
- Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等
- Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等
- Android快速实现扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)
- Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等
- android笔记之zxing生成二维码、条码
- Zxing图片识别 从相册选取二维码图片进行解析总结
- iOS相册图片二维码识别
- android仿微信识别相册中二维码图片信息
- Android实现识别相册二维码
- kubernetes client-go包使用示例
- 链接重定位
- Android开发中常见的5大内存泄漏问题及解决办法
- Web Service工作原理及实例
- 专业实习03
- Android Zxing 相册二维码/条码图片识别
- Intellij IDEA创建maven项目无java文件问题
- 【理解HotSpot虚拟机】类的加载机制
- 使用SoapUI 测试Web Service
- Redhat7 Firewalld防火墙
- json_JSON数据格式和 serialize数据格式的异同和使用
- C++ SDL教程翻译 Lesson 03 Event Driven Programming
- 如何写一个单利模式
- 磁盘阵列 和 分布式文件系统有什么区别?