信息发布→ 登录 注册 退出

Java Spring boot实现生成二维码

发布时间:2026-01-11

点击量:
目录
  • 一、引入spring boot依赖:
  • 二、工具类代码:
  • 三、调用工具类生成二维码
    • 1、将链接生成二维码图片并保存到指定路径
    • 2、将链接生成二维码直接显示在页面
    • 3、将以get请求传参链接生成二维码
  • 总结

    一、引入spring boot依赖:

       <!--引入生成二维码的依赖-->
       <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
       <dependency>
           <groupId>com.google.zxing</groupId>
           <artifactId>core</artifactId>
           <version>3.3.0</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
       <dependency>
           <groupId>com.google.zxing</groupId>
           <artifactId>javase</artifactId>
           <version>3.3.0</version>
       </dependency>
    

    二、工具类代码:

    import com.google.zxing.*;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Hashtable;
    
    /**
     * 二维码生成工具类
     */
    public class QrCodeUtils {
        private static final String CHARSET = "utf-8";
        public static final String FORMAT = "JPG";
        // 二维码尺寸
        private static final int QRCODE_SIZE = 300;
        // LOGO宽度
        private static final int LOGO_WIDTH = 60;
        // LOGO高度
        private static final int LOGO_HEIGHT = 60;
    
        /**
         * 生成二维码
         *
         * @param content      二维码内容
         * @param logoPath     logo地址
         * @param needCompress 是否压缩logo
         * @return 图片
         * @throws Exception
         */
        public static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
                    hints);
            int width = bitMatrix.getWidth();
            int height = bitMatrix.getHeight();
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }
            if (logoPath == null || "".equals(logoPath)) {
                return image;
            }
            // 插入图片
            QrCodeUtils.insertImage(image, logoPath, needCompress);
            return image;
        }
    
        /**
         * 插入LOGO
         *
         * @param source       二维码图片
         * @param logoPath     LOGO图片地址
         * @param needCompress 是否压缩
         * @throws IOException
         */
        private static void insertImage(BufferedImage source, String logoPath,
                                        boolean needCompress) throws Exception {
            File file = new File(logoPath);
            if (!file.exists()) {
                System.err.println(""+logoPath+"   该文件不存在!");
                return;
            }
            Image src = ImageIO.read(new File(logoPath));
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            if (needCompress) { // 压缩LOGO
                if (width > LOGO_WIDTH) {
                    width = LOGO_WIDTH;
                }
                if (height > LOGO_HEIGHT) {
                    height = LOGO_HEIGHT;
                }
                Image image = src.getScaledInstance(width, height,
                        Image.SCALE_SMOOTH);
                BufferedImage tag = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                g.drawImage(image, 0, 0, null); // 绘制缩小后的图
                g.dispose();
                src = image;
            }
            // 插入LOGO
            Graphics2D graph = source.createGraphics();
            int x = (QRCODE_SIZE - width) / 2;
            int y = (QRCODE_SIZE - height) / 2;
            graph.drawImage(src, x, y, width, height, null);
            Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
            graph.setStroke(new BasicStroke(3f));
            graph.draw(shape);
            graph.dispose();
        }
    
        /**
         * 生成二维码(指定路径保存)
         *
         * @param content 内容
         * @param imgPath logo图片地址(内嵌图片)
         * @param destPath 生成二维码存放地址
         * @param needCompress 是否压缩logo
         * @throws Exception
         */
        public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
            BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress);
            mkdirs(destPath);
            // String file = new Random().nextInt(99999999)+".jpg";
            // ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
            ImageIO.write(image, FORMAT, new File(destPath));
        }
    
        /**
         * 生成二维码(直接将二维码以图片输出流返回)
         *
         * @param content 内容
         * @param imgPath logo图片地址(内嵌图片)
         * @param needCompress 是否压缩logo
         * @return
         * @throws Exception
         */
        public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception {
            BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress);
            return image;
        }
    
        public static void mkdirs(String destPath) {
            File file = new File(destPath);
            // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
            if (!file.exists() && !file.isDirectory()) {
                file.mkdirs();
            }
        }
    
        /**
         * 生成二维码(内嵌LOGO)
         *
         * @param content      内容
         * @param logoPath     LOGO地址
         * @param output       输出流
         * @param needCompress 是否压缩LOGO
         * @throws Exception
         */
        public static void encode(String content, String logoPath, OutputStream output, boolean needCompress)
                throws Exception {
            BufferedImage image = QrCodeUtils.createImage(content, logoPath, needCompress);
            ImageIO.write(image, FORMAT, output);
        }
    
        /**
         * 获取指定文件的输入流,获取logo
         *
         * @param logoPath 文件的路径
         * @return
         */
        public static InputStream getResourceAsStream(String logoPath) {
            return QrCodeUtils.class.getResourceAsStream(logoPath);
        }
    
        /**
         * 解析二维码
         *
         * @param file
         *            二维码图片
         * @return
         * @throws Exception
         */
        public static String decode(File file) throws Exception {
            BufferedImage image;
            image = ImageIO.read(file);
            if (image == null) {
                return null;
            }
            BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            Result result;
            Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
            result = new MultiFormatReader().decode(bitmap, hints);
            String resultStr = result.getText();
            return resultStr;
        }
    
        /**
         * 解析二维码
         *
         * @param path
         *            二维码图片地址
         * @return
         * @throws Exception
         */
        public static String decode(String path) throws Exception {
            return QrCodeUtils.decode(new File(path));
        }
    
    	//测试一:
        public static void main(String[] args) throws Exception {
            String text = "https://blog.csdn.net/weixin_43763430";
            String logoPath = "D:\\qrCode\\logo.jpg";
            String destPath = "D:\\qrCode\\csdn.jpg";
            QrCodeUtils.encode(text,logoPath,destPath,true);
        }
    }
    

    三、调用工具类生成二维码

    1、将链接生成二维码图片并保存到指定路径

    工具类中的主方法是指定了二维码链接的内容是博客地址,并保存在D:\qrCode\csdn.jpg,二维码嵌套了头像的图片,期望实现的是生成二维码后被扫码直接进入到博客也没。如若不嵌入头像,直接将logoPath参数设为null。

    	//测试一:
        public static void main(String[] args) throws Exception {
            String text = "https://blog.csdn.net/weixin_43763430";
            String logoPath = "D:\\qrCode\\logo.jpg";
            String destPath = "D:\\qrCode\\csdn.jpg";
            QrCodeUtils.encode(text,logoPath,destPath,true);
        }
    

    运行该主方法后,可在指定路径中看到生成的二维码图片。

    2、将链接生成二维码直接显示在页面

    运用spring boot生成二维码无需将保存二维码的图片,只须前端调用springboot接口即可在页面上显示二维码。实现了实时生成二维码。Controller层接口代码示例如下:

    	@GetMapping("/anon/coupon/qrCodeTest")
        @ApiOperation(value = "获取二维码")
        public void qrCodeTest(HttpServletResponse response) throws Exception {
            String text = "https://blog.csdn.net/weixin_43763430";
            String logoPath = "D:\\qrCode\\logo.jpg";
            //String destPath = "D:\\qrCode\\csdn.jpg";
            QrCodeUtils.encode(text,logoPath,response.getOutputStream(),true);
        }
    

    打开浏览器访问该接口地址,页面就会显示生成的二维码。扫描二维码即可进入到博客页面。

    3、将以get请求传参链接生成二维码

    二维码运用到各种业务中,通常需要根据不同用户识别其相对应的内容,如以上示例是访问的博客主页面,如若想根据访问者传递的参数访问博客中特定的文章,文章访问各篇文章是用的get请求方式,即可根据传参实现get请求传入不同参数生成二维码的内容不同。

    	@GetMapping("/anon/coupon/qrCodeTest")
        @ApiOperation(value = "获取二维码")
        public void qrCodeTest(@RequestParam(value = "id") String id,HttpServletResponse response) throws Exception {
            String text = "https://blog.csdn.net/weixin_43763430/article/details/" + id;
            String logoPath = "D:\\qrCode\\logo.jpg";
            //String destPath = "D:\\qrCode\\csdn.jpg";
            QrCodeUtils.encode(text,logoPath,response.getOutputStream(),true);
        }
    

    用浏览器访问该接口地址,页面生成二维码,用手机扫描二维码即可跳转到博客中该篇文章页面。

    总结

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!