生成和解析二维码(zxing)

    二维码因其便捷性已经被广泛的使用,进行开发的时候客户也经常会提出这样的需求。这里提供了对生成二维码和解析图片二维码的简单封装。

首先在gradle中引入zxing:

compile 'com.google.zxing:core:3.1.0'

 然后是工具类:

/**
 * 解析二维码的工具类<br/>
 * 1.必须在项目中引入zxing
 * 2.支持生成二维码
 * 3.解析图片中的二维码
 * 4.把二维码保存到本地
 * Created by hsji on 2016/1/14.
 */
public class QRCodeUtils
{
    private static final String TAG = QRCodeUtils.class.getSimpleName();
    public static final String CHARSET_UTF_8 = "UTF-8";
    public static final String CHARSET_GBK = "GBK";

    /**
     * 默认生成方法
     *
     * @param context
     * @param content
     * @return
     */
    public static final Bitmap encodeAsBitmap(Context context, String content)
    {
        //默认二维码的宽度为屏幕宽度的一半
        int size = Math.min(context.getResources().getDisplayMetrics().widthPixels, context.getResources().getDisplayMetrics().heightPixels) / 2;
        return encodeAsBitmap(content, CHARSET_UTF_8, size);
    }

    /**
     * 生成二维码
     *
     * @param content    字符串内容
     * @param encodeType 编码格式
     * @param size       二维码的尺寸
     * @return
     */
    public static final Bitmap encodeAsBitmap(String content, String encodeType, int size)
    {
        if (TextUtils.isEmpty(content))
        {
            return null;
        }
        Map<EncodeHintType, Object> hints = null;
        hints = new EnumMap<>(EncodeHintType.class);
        //指定编码格式
        hints.put(EncodeHintType.CHARACTER_SET, encodeType);
        //指定纠错等级 L:7%  M:15%  Q:25%  H:30%
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        BitMatrix result;
        try
        {
            result = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
        } catch (IllegalArgumentException e)
        {
            e.printStackTrace();
            return null;
        } catch (WriterException e)
        {
            e.printStackTrace();
            return null;
        }

        int[] pixels = new int[size * size];
        for (int y = 0; y < size; y++)
        {
            int offset = y * size;
            for (int x = 0; x < size; x++)
            {
                pixels[offset + x] = result.get(x, y) ? 0x000000 : 0xffffff;
            }
        }
        //没有透明度  节省内存
        return Bitmap.createBitmap(pixels, size, size, Bitmap.Config.RGB_565);
    }

    /**
     * 解析二维码
     *
     * @param path
     * @return
     */
    public static String decode(String path)
    {
        if (TextUtils.isEmpty(path))
        {
            return null;
        }
        Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
        //设置编码格式
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET_UTF_8);
        Bitmap src = BitmapFactory.decodeFile(path);
        int[] pixels = new int[src.getWidth() * src.getHeight()];
        src.getPixels(pixels, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight());
        RGBLuminanceSource source = new RGBLuminanceSource(src.getWidth(), src.getHeight(), pixels);
        BinaryBitmap bb = new BinaryBitmap(new HybridBinarizer(source));
        MultiFormatReader reader = new MultiFormatReader();
        try
        {
            Result result = reader.decode(bb, hints);
            return result.getText();
        } catch (NotFoundException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 保存二维码到本地<br/>
     * 直接保存二维码得到的是一张黑图(我也不知道什么原因)
     *
     * @param src
     * @param path
     * @return
     */
    public static final boolean saveQRCode(Bitmap src, String path)
    {
        Bitmap target = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(target);
        canvas.drawBitmap(src, 0.0f, 0.0f, new Paint());
        BufferedOutputStream bos = null;
        try
        {
            File file = new File(path);
            if (file.exists())
            {
                file.delete();
            }
            bos = new BufferedOutputStream(new FileOutputStream(file));
            target.compress(Bitmap.CompressFormat.PNG, 100, bos);
        } catch (Exception e)
        {
            e.printStackTrace();
            return false;
        } finally
        {
            if (bos != null)
            {
                try
                {
                    bos.flush();
                    bos.close();
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
            if (target != null && !target.isRecycled())
            {
                target.recycle();
                target = null;
            }
        }
        return true;
    }
}

 最后是使用方法:

        //生成二维码 显示在ImageView中
        iv.setImageBitmap(QRCodeUtils.encodeAsBitmap(this, "https://www.baidu.com"));
        //生成二维码并保存   之后在解析此二维码
        if (FileUtils.isExternalFileSystemAccessible())
        {
            if (QRCodeUtils.saveQRCode(QRCodeUtils.encodeAsBitmap(this, "https://www.baidu.com"), Environment.getExternalStorageDirectory() + "/qrcode.png"))
            {
                Toast.makeText(this, "二维码保存成功!", Toast.LENGTH_SHORT).show();
                mTextViewResult.setText(QRCodeUtils.decode(Environment.getExternalStorageDirectory() + "/qrcode.png"));
            }
        } else
        {
            Toast.makeText(this, "存储空间暂不可用!", Toast.LENGTH_SHORT).show();
        }

 

posted @ 2016-01-14 14:10  听懂·动听  阅读(1449)  评论(0编辑  收藏  举报