android 从图片获取二维码

来源:互联网 发布:java 类似于w3c的网站 编辑:程序博客网 时间:2024/05/16 12:51

     之前的博客我记得讲过关于扫描二维码的内容,昨天,组长让我不仅可以扫描获取二维码,还可以通过图片获取里面的二维码。比如别人拍了一张二维码的照片,发送给你,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;    //此时的bitmapnull,这段代码之后,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 从图片获取二维码就讲完了。


就这么简单。



















0 0
原创粉丝点击