二维码因其便捷性已经被广泛的使用,进行开发的时候客户也经常会提出这样的需求。这里提供了对生成二维码和解析图片二维码的简单封装。
首先在gradle中引入zxing:
compile 'com.google.zxing:core:3.1.0'
然后是工具类:
/** * 解析二维码的工具类 * 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; } Maphints = 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 hints = new Hashtable (); //设置编码格式 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; } /** * 保存二维码到本地 * 直接保存二维码得到的是一张黑图(我也不知道什么原因) * * @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(); }