这里有新鲜出炉的精品教程,程序狗速度看过来!
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
这篇文章主要为大家详细介绍了 Android 从图片获取二维码的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
之前的博客我记得讲过关于扫描二维码的内容,昨天,组长让我不仅可以扫描获取二维码,还可以通过图片获取里面的二维码。比如别人拍了一张二维码的照片,发送给你,app 应该可以获取图片的二维码。
自己在网上查了资料,发现其实也很简单,用 ZXing jar 包里的获取图片二维码的 QRCodeReader 就基本可以了。不过大部分的内容,我自己也不明白,大家如果有兴趣,可以自己去查找资料。
1. 点击按钮后,跳转到相册,选择有二维码的图片,返回到解析二维码的界面。这时通过返回的 URI 获取图片的路径。
- case CHOOSE_PIC:
- String[] proj = new String[] {
- MediaStore.Images.Media.DATA
- };
- Cursor cursor = QRCodeActivity.this.getContentResolver().query(data.getData(), proj, null, null, null);
- if (cursor.moveToFirst()) {
- int columnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
- System.out.println(columnIndex);
- //获取到用户选择的二维码图片的绝对路径
- imgPath = cursor.getString(columnIndex);
- }
- cursor.close();
- //获取解析结果
- Result ret = parseQRcodeBitmap(imgPath);
- if (ret == null) {
- Toast.makeText(QRCodeActivity.this, getString(R.string.load_two_dimensional_error), Toast.LENGTH_LONG).show();
- } else {
- // Toast.makeText(QRCodeActivity.this,"解析结果:" + ret.toString(), Toast.LENGTH_LONG).show();
- Intent intent = new Intent();
- intent.putExtra(Intents.Scan.RESULT, ret.toString());
- this.setResult(Activity.RESULT_OK, intent);
- this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
- finish();
- }
- break;
这个就是通过 ContentResolver 查询 URI 获取图片的路径,然后调用 parseQRcodeBitmap(imgPath)获取图片的二维码。
2. 通过图片路径进行解析图片,获取图片的二维码值。
- //解析二维码图片,返回结果封装在Result对象中
- private com.google.zxing.Result parseQRcodeBitmap(String bitmapPath) {
- //解析转换类型UTF-8
- Hashtable < DecodeHintType,
- String > hints = new Hashtable < DecodeHintType,
- String > ();
- hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
- //获取到待解析的图片
- BitmapFactory.Options options = new BitmapFactory.Options();
- //如果我们把inJustDecodeBounds设为true,那么BitmapFactory.decodeFile(String path, Options opt)
- //并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你
- options.inJustDecodeBounds = true;
- //此时的bitmap是null,这段代码之后,options.outWidth 和 options.outHeight就是我们想要的宽和高了
- Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath, options);
- //我们现在想取出来的图片的边长(二维码图片是正方形的)设置为400像素
- /**
- options.outHeight = 400;
- options.outWidth = 400;
- options.inJustDecodeBounds = false;
- bitmap = BitmapFactory.decodeFile(bitmapPath, options);
- */
- //以上这种做法,虽然把bitmap限定到了我们要的大小,但是并没有节约内存,如果要节约内存,我们还需要使用inSimpleSize这个属性
- options.inSampleSize = options.outHeight / 400;
- if (options.inSampleSize <= 0) {
- options.inSampleSize = 1; //防止其值小于或等于0
- }
- /**
- * 辅助节约内存设置
- *
- * options.inPreferredConfig = Bitmap.Config.ARGB_4444; // 默认是Bitmap.Config.ARGB_8888
- * options.inPurgeable = true;
- * options.inInputShareable = true;
- */
- options.inJustDecodeBounds = false;
- bitmap = BitmapFactory.decodeFile(bitmapPath, options);
- //新建一个RGBLuminanceSource对象,将bitmap图片传给此对象
- RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(bitmap);
- //将图片转换成二进制图片
- BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
- //初始化解析对象
- QRCodeReader reader = new QRCodeReader();
- //开始解析
- Result result = null;
- try {
- result = reader.decode(binaryBitmap, hints);
- } catch(Exception e) {
- // TODO: handle exception
- }
- return result;
- }
这里首先获取图片的 bitmap,需要把获取的 bitmap 专为一定的大小,通过 options.inSampleSize 来实现,然后通过
- //新建一个RGBLuminanceSource对象,将bitmap图片传给此对象
- RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(bitmap);
- //将图片转换成二进制图片
- BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
- //初始化解析对象
- QRCodeReader reader = new QRCodeReader();
将 bitmap 的二维码转换成图片,然后又将图片转成二进制图片,调用 QRCodeReader 的 result = reader.decode(binaryBitmap, hints); 代码把二进制图片转成二维码,然后直接获取返回值的字符串就是二维码值。
其中用到了一个自定义的类 RGBLuminanceSource,主要功能是将图片的二维码内容获取到,把除二维码的内容过滤,方便接下来的解析二维码。
- package com.zwcode.p6spro.util;
- import java.io.FileNotFoundException;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import com.google.zxing.LuminanceSource;
- public class RGBLuminanceSource extends LuminanceSource {
- private final byte[] luminances;
- public RGBLuminanceSource(Bitmap bitmap) {
- super(bitmap.getWidth(), bitmap.getHeight());
- //得到图片的宽高
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
- //得到图片的像素
- int[] pixels = new int[width * height];
- //
- bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
- //为了测量纯解码速度,我们将整个图像灰度阵列前面,这是一样的通道
- // YUVLuminanceSource在现实应用。
- //得到像素大小的字节数
- luminances = new byte[width * height];
- //得到图片每点像素颜色
- for (int y = 0; y < height; y++) {
- int offset = y * width;
- for (int x = 0; x < width; x++) {
- int pixel = pixels[offset + x];
- int r = (pixel >> 16) & 0xff;
- int g = (pixel >> 8) & 0xff;
- int b = pixel & 0xff;
- //当某一点三种颜色值相同时,相应字节对应空间赋值为其值
- if (r == g && g == b) {
- luminances[offset + x] = (byte) r;
- }
- //其它情况字节空间对应赋值为:
- else {
- luminances[offset + x] = (byte)((r + g + g + b) >> 2);
- }
- }
- }
- }
- public RGBLuminanceSource(String path) throws FileNotFoundException {
- this(loadBitmap(path));
- }
- @Override public byte[] getMatrix() {
- return luminances;
- }
- @Override public byte[] getRow(int arg0, byte[] arg1) {
- if (arg0 < 0 || arg0 >= getHeight()) {
- throw new IllegalArgumentException("Requested row is outside the image: " + arg0);
- }
- int width = getWidth();
- if (arg1 == null || arg1.length < width) {
- arg1 = new byte[width];
- }
- System.arraycopy(luminances, arg0 * width, arg1, 0, width);
- return arg1;
- }
- private static Bitmap loadBitmap(String path) throws FileNotFoundException {
- Bitmap bitmap = BitmapFactory.decodeFile(path);
- if (bitmap == null) {
- throw new FileNotFoundException("Couldn't open " + path);
- }
- return bitmap;
- }
- }
这样就可以识别图片的二维码了,用这个功能一定要先导入 ZXing jar 包,这个很简单,网上有很多介绍,大家自己可以查找一下。
Android 从图片获取二维码就讲完了。
就这么简单。
来源: http://www.phperz.com/article/17/0819/337676.html