JAVA实现动态二维码输出

一、控制层

 1     @GetMapping(value = "/generate")
 2     @ResponseBody
 3     public void generateQR(@RequestParam("url")String url, HttpServletResponse response) {
 4         BufferedImage imageWithLogo;
 5         response.setHeader("Pragma", "No-cache");
 6         response.setHeader("Cache-Control", "no-cache");
 7         response.setDateHeader("Expires", 0);
 8         response.setContentType("image/jpeg");
 9         InputStream resourceAsStream = this.getClass().getResourceAsStream("/logo/logo.png");
10         imageWithLogo = QRCodeUtil.createImageWithLogo(url, resourceAsStream, true);
11         try(ServletOutputStream sos = response.getOutputStream()){
12             ImageIO.write(imageWithLogo, "jpeg", sos);
13         } catch (IOException e) {
14             e.printStackTrace();
15         }
16     }

二、QRCodeUtil

  1 package com.nvxclouds.report.biz.utils;
  2 
  3 import com.google.zxing.BarcodeFormat;
  4 import com.google.zxing.EncodeHintType;
  5 import com.google.zxing.MultiFormatWriter;
  6 import com.google.zxing.WriterException;
  7 import com.google.zxing.common.BitMatrix;
  8 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  9 
 10 import javax.imageio.ImageIO;
 11 import java.awt.*;
 12 import java.awt.geom.RoundRectangle2D;
 13 import java.awt.image.BufferedImage;
 14 import java.io.IOException;
 15 import java.io.InputStream;
 16 import java.util.Hashtable;
 17 
 18 /**
 19  * @Auther: ShouZhi@Duan
 20  * @Date: 2021/3/22 15:18
 21  * @Description:
 22  */
 23 public class QRCodeUtil {
 24     private static final String CHARSET = "utf-8";
 25 
 26     // 二维码尺寸
 27     private static final int QRCODE_SIZE = 300;
 28     // LOGO宽度
 29     private static final int LOGO_WIDTH = 80;
 30     // LOGO高度
 31     private static final int LOGO_HEIGHT = 80;
 32 
 33     /**
 34      * 生成不含Logo的二维码
 35      * @param content 二维码跳转资源
 36      * @return
 37      */
 38     public static BufferedImage createImage(String content) {
 39         Hashtable<EncodeHintType, Object> hints = new Hashtable();
 40         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
 41         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
 42         hints.put(EncodeHintType.MARGIN, 1);
 43         BitMatrix bitMatrix = null;
 44         try {
 45             bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
 46         } catch (WriterException e) {
 47             e.printStackTrace();
 48         }
 49         int width = bitMatrix.getWidth();
 50         int height = bitMatrix.getHeight();
 51         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 52         for (int x = 0; x < width; x++) {
 53             for (int y = 0; y < height; y++) {
 54                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
 55             }
 56         }
 57         return image;
 58     }
 59 
 60 
 61     /**
 62      * 生成含Logo的二维码
 63      * @param content 二维码跳转资源
 64      * @param logoStream Logo图片资源
 65      * @param compress Logo是否需要压缩
 66      * @return
 67      */
 68     public static BufferedImage createImageWithLogo(String content, InputStream logoStream, boolean compress) {
 69         Hashtable<EncodeHintType, Object> hints = new Hashtable();
 70         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
 71         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
 72         hints.put(EncodeHintType.MARGIN, 1);
 73         BitMatrix bitMatrix = null;
 74         try {
 75             bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
 76         } catch (WriterException e) {
 77             e.printStackTrace();
 78         }
 79         int width = bitMatrix.getWidth();
 80         int height = bitMatrix.getHeight();
 81         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 82         for (int x = 0; x < width; x++) {
 83             for (int y = 0; y < height; y++) {
 84                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
 85             }
 86         }
 87         insertImage(image,logoStream,compress);
 88         return image;
 89     }
 90 
 91 
 92     /**
 93      * 插入LOGO
 94      * @param source       二维码图片
 95      * @param logoPath     LOGO图片地址
 96      * @param needCompress 是否压缩
 97      * @throws Exception
 98      */
 99     public static void insertImage(BufferedImage source, InputStream logoPath, boolean needCompress)  {
100         Image src = null;
101         try {
102             src = ImageIO.read(logoPath);
103         } catch (IOException e) {
104             e.printStackTrace();
105         }
106         int width = src.getWidth(null);
107         int height = src.getHeight(null);
108         if (needCompress) {
109             // 压缩LOGO
110             if (width > LOGO_WIDTH) {
111                 width = LOGO_WIDTH;
112             }
113             if (height > LOGO_HEIGHT) {
114                 height = LOGO_HEIGHT;
115             }
116             Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
117             BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
118             Graphics g = tag.getGraphics();
119             // 绘制缩小后的图
120             g.drawImage(image, 0, 0, null);
121             g.dispose();
122             src = image;
123         }
124         // 插入LOGO
125         Graphics2D graph = source.createGraphics();
126         int x = (QRCODE_SIZE - width) / 2;
127         int y = (QRCODE_SIZE - height) / 2;
128         graph.drawImage(src, x, y, width, height, null);
129         Shape shape = new RoundRectangle2D.Float(x, y, width, width, 12, 12);
130         graph.setStroke(new BasicStroke(3f));
131         graph.draw(shape);
132         graph.dispose();
133     }
134 }

 

上一篇:Java创建图片并绘图


下一篇:FastDFS - 开源的分布式文件系统