二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
随着科技的进步,在我们生活中会越来越多得用到二维码,比如:生活支付码,健康码,公交地铁乘车码,微信好友名片码等等,废话不多说,今天我们就用java来写一套自动生成和读取二维码的工具。
第一步:引入需要的jar包
<!-- zxing二维码 start--> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.3</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.3.3</version> </dependency> <!-- zxing二维码 end-->
第二步:编写util类 添加三个方法 1.生成二维码 2.识别二维码 3.给二维码加logo
/** * 生成二维码 */ public static void QREncode(String content,String logoFilePath) throws WriterException, IOException { Map<EncodeHintType, Object> hints = new HashMap<>(); //内容编码格式 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定纠错等级 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //设置二维码边的空度,非负数 hints.put(EncodeHintType.MARGIN, 1); // 图像宽度 int width = 200; // 图像高度 int height = 200; BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); //输出原始(不带logo)二维码路径 String originFilePath="D:\\origin.png"; MatrixToImageWriter.writeToPath(bitMatrix, "PNG", new File(originFilePath).toPath()); //logo默认黑白,需要设置BLACK、WHITE MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); BufferedImage bufferedImage = LogoMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix,matrixToImageConfig), new File(logoFilePath)); //输出带logo二维码路径 String resultFilePath="D:\\result.png"; ImageIO.write(bufferedImage, "gif", new File(resultFilePath)); System.out.println("输出成功."); } /** * 识别二维码 */ public static void QRReader(String filePath) throws IOException, NotFoundException { File file=new File(filePath); MultiFormatReader formatReader = new MultiFormatReader(); //读取指定的二维码文件 BufferedImage bufferedImage =ImageIO.read(file); BinaryBitmap binaryBitmap= new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage))); //定义二维码参数 Map hints= new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); com.google.zxing.Result result = formatReader.decode(binaryBitmap, hints); //输出相关的二维码信息 System.out.println("解析结果:"+result.toString()); System.out.println("二维码格式类型:"+result.getBarcodeFormat()); System.out.println("二维码文本内容:"+result.getText()); bufferedImage.flush(); } /** * 二维码添加logo * @param matrixImage 源二维码图片 * @param logoFile logo图片 * @return 返回带有logo的二维码图片 */ public static BufferedImage LogoMatrix(BufferedImage matrixImage, File logoFile) throws IOException{ //读取二维码图片,并构建绘图对象 Graphics2D g2 = matrixImage.createGraphics(); int matrixWidth = matrixImage.getWidth(); int matrixHeigh = matrixImage.getHeight(); //读取Logo图片 BufferedImage logo = ImageIO.read(logoFile); //开始绘制图片 g2.drawImage(logo,matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null); BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); g2.setStroke(stroke);// 设置笔画对象 //指定弧度的圆角矩形 RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20); g2.setColor(Color.white); // 绘制圆弧矩形 g2.draw(round); //设置logo 有一道灰色边框 BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); // 设置笔画对象 g2.setStroke(stroke2); RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20); g2.setColor(new Color(128,128,128)); // 绘制圆弧矩形 g2.draw(round2); g2.dispose(); matrixImage.flush() ; return matrixImage ; }
第三步:测试生成一下二维码
public static void main(String[] args) { try { QREncode("程序员技术大联盟哈哈哈哈",System.getProperty("user.dir")+"\\demo-api-service\\src\\main\\resource\\photo\\logo.png"); QRReader(System.getProperty("user.dir")+"\\demo-api-service\\src\\main\\resource\\photo\\result.png"); } catch (Exception e) { e.printStackTrace(); } }
生成的二维码图片如下:
识别二维码的结果如下:
第四步:在写一个工具方法返回二维码给前端
/** * 生成二维码并返回 */ public static BufferedImage QREncodeReturn(String content,File logoFile) throws Exception{ Map<EncodeHintType, Object> hints = new HashMap<>(); //内容编码格式 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定纠错等级 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //设置二维码边的空度,非负数 hints.put(EncodeHintType.MARGIN, 1); int width = 250; // 图像宽度 int height = 250; // 图像高度 BitMatrix bitMatrix = null; BufferedImage bufferedImage = null; bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix,matrixToImageConfig); //直接return bufferedImage 是无logo; return LogoMatrix(bufferedImage,logoFile); }
第五步:写一个controller接口暴露出去通过浏览器调用实现动态生成二维码
//获取二维码图片 @RequestMapping(value = "qrCode", method = RequestMethod.GET) public void getBarCodeImage(String context, HttpServletResponse response){ try{ //设置页面不缓存 response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.getOutputStream(); //设置输出的内容的类型为JPEG图像 response.setContentType("image/jpeg"); File logoFile=new File("G:\\code\\FrameDemo\\demo-service\\src\\main\\resource\\photo\\logo.png"); BufferedImage bufferedImage = QREncodeReturn(context,logoFile); //写给浏览器 ImageIO.write(bufferedImage, "jpeg", response.getOutputStream()); }catch (Exception e){ e.printStackTrace(); } }
第六步:运行起来通过浏览器输入不同参数动态生成二维码
源码地址: