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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 滴滴客人不付款怎么办 汽车租赁公司手续怎么办 北京市出租车运营证怎么办 滴滴催款不给怎么办 手机落在滴滴上怎么办 滴滴上遗失手机怎么办 12328不受理投诉怎么办 爱上租提前退租怎么办 房子被转租了怎么办 房子不能转租要怎么办 买房按揭没通过怎么办 出租车拉东西了怎么办 下水道掉了刷子怎么办 绿萝生了小虫子怎么办 车在外地出险怎么办 宜昌小学生作业太多怎么办 南宁怎么办滴滴营运证 在美容院被骗了怎么办 怀孕了没钱打胎怎么办 淘宝买了假戴森怎么办 播放权限已过期怎么办 青岛永旺过期怎么办 商家有欺诈行为怎么办 被酒楼欺骗消费怎么办 被强制性消费了怎么办 邮政无运单号怎么办? 劳动仲裁立案后怎么办 被执行公司没钱怎么办 厕所主管道堵塞怎么办 下水道主干堵了怎么办 上海电瓶车被扣怎么办 厨房公共管道漏水怎么办 厨房下水管不通怎么办 厨房下水管道堵塞怎么办 阳台管道堵了怎么办 卫生间下水道堵了怎么办 带婴儿不够睡怎么办 下水管水泥堵塞怎么办 协年年检不合格怎么办 江苏省醉驾了怎么办 货运资格证ic卡怎么办