您的位置:首页 > 其它

使用ZXing扫码实现扫手机本地图片的二维码内容

2018-03-26 16:27 423 查看
ZXing这个第三方是我用的第三方,用来扫描二维码的,之前没有看到ZXing还提供了扫描本地图片二维码的功能,现在整理如下。

跳转到选取本地图片的页面Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("iamge/*");
startActivityForResult(intent, 300);然后选取图片之后来到onActivityResult回调@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100) {
//获取照片数据
Bitmap camera = data.getParcelableExtra("data");
iv1.setImageBitmap(camera);
}
if (requestCode == 200) {
if (data != null) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));
iv1.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
if (requestCode == 300) {
String photoPath = getRealFilePath(this, data.getData());
if (photoPath == null) {
LogUtil.fussenLog().d("路径获取失败");
} else {
//解析图片
prasePhoto(photoPath);
}
}
}

我们只用关心requestCode 为  300 的这种情况
里面有两个自定义的方法   分别是:
getRealFilePath  方法  和  解析图片的  prasePhoto 方法
getRealFilePath方法  是用来获取选取的图片的绝对地址
具体方法在之前的一篇文章介绍过:根据uri获取文件路径
这里直接贴出来方法: private String getRealFilePath(Context c, Uri uri) {
String result;
Cursor cursor = c.getContentResolver().query(uri,
new String[]{MediaStore.Images.ImageColumns.DATA},//
null, null, null);
if (cursor == null) result = uri.getPath();
else {
cursor.moveToFirst();
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(index);
cursor.close();
}
return result;
}其实之前都是准备工作,接下来就是主要的核心内容了,就是用ZXing扫描一直路径的图片的功能了
就是parsePhoto方法   由于这个方法是耗时的  所以需要用AsyncTask  或者Rxjava  这里用的是AsyncTask
具体代码如下: private void prasePhoto(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) {
LogUtil.fussenLog().d("图片获取失败,请重试");
} else {
// 识别出图片二维码/条码,内容为s
btn3.setText(s);
LogUtil.fussenLog().d(s);
}
}
}.execute(path);
}
里面有一个类是自己写的  QRCodeDecoder  里面是最最重要的代码  如下: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);
allForm
b984
ats.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;
}
}
}

以上就是本文最最重要的代码整理成工具类
里面三个方法实际上就是  先把传入的图片的绝对地址转换成Bitmap,然后把Bitmap用zxing里面的方法读取图片的二维码扫描结果然后在整合返回就可以了,实际上只调用最上面那个syncDecodeQRCode这个方法就可以了。

----------------------------------------------------------------------------------------------------------------
Ps,别忘了这个是耗时任务,所以有些要考虑的别忘考虑了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐