zoukankan      html  css  js  c++  java
  • spring boot:用zxing生成二维码,支持logo(spring boot 2.3.2)

    一,zxing是什么?

    1,zxing的用途

    如果我们做二维码的生成和扫描,通常会用到zxing这个库,

    ZXing是一个开源的,用Java实现的多种格式的1D/2D条码图像处理库。

    zxing还可以实现使用手机的内置的摄像头完成条形码的扫描及解码

    2,zxing官方项目地址:

    https://github.com/zxing/zxing

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,演示项目的相关信息

    1,项目地址

    https://github.com/liuhongdi/qrcode

    2, 项目功能说明:

        生成二维码直接展示

        生成二维码保存成图片

        解析二维码图片中的文字信息

    3,项目结构,如图:

    三,配置文件说明

    1,pom.xml

            <!--qrcode begin-->
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>core</artifactId>
                <version>3.4.0</version>
            </dependency>
    
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>javase</artifactId>
                <version>3.4.0</version>
            </dependency>
            <!--qrcode   end-->

    导入zxing库供生成qrcode使用

    四,java代码说明

    1,QrCodeUtil.java

    /**
     * 二维码工具类
     * by liuhongdi
     */
    public class QrCodeUtil {
    
        //编码格式,采用utf-8
        private static final String UNICODE = "utf-8";
        //图片格式
        private static final String FORMAT = "JPG";
        //二维码宽度像素pixels数量
        private static final int QRCODE_WIDTH = 300;
        //二维码高度像素pixels数量
        private static final int QRCODE_HEIGHT = 300;
        //LOGO宽度像素pixels数量
        private static final int LOGO_WIDTH = 100;
        //LOGO高度像素pixels数量
        private static final int LOGO_HEIGHT = 100;
    
        //生成二维码图片
        //content 二维码内容
        //logoPath logo图片地址
        private static BufferedImage createImage(String content, String logoPath) throws Exception {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, UNICODE);
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_WIDTH, QRCODE_HEIGHT,
                    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;
            }
            // 插入图片
            QrCodeUtil.insertImage(image, logoPath);
            return image;
        }
    
        //在图片上插入LOGO
        //source 二维码图片内容
        //logoPath LOGO图片地址
        private static void insertImage(BufferedImage source, String logoPath) throws Exception {
            File file = new File(logoPath);
            if (!file.exists()) {
                throw new Exception("logo file not found.");
            }
            Image src = ImageIO.read(new File(logoPath));
            int width = src.getWidth(null);
            int height = src.getHeight(null);
                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_WIDTH - width) / 2;
            int y = (QRCODE_HEIGHT - 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();
        }
    
        //生成带logo的二维码图片,保存到指定的路径
        // content 二维码内容
        // logoPath logo图片地址
        // destPath 生成图片的存储路径
        public static String save(String content, String logoPath, String destPath) throws Exception {
            BufferedImage image = QrCodeUtil.createImage(content, logoPath);
            File file = new File(destPath);
            String path = file.getAbsolutePath();
            File filePath = new File(path);
            if (!filePath.exists() && !filePath.isDirectory()) {
                filePath.mkdirs();
            }
            String fileName = file.getName();
            fileName = fileName.substring(0, fileName.indexOf(".")>0?fileName.indexOf("."):fileName.length())
                    + "." + FORMAT.toLowerCase();
            System.out.println("destPath:"+destPath);
            ImageIO.write(image, FORMAT, new File(destPath));
            return fileName;
        }
    
        //生成二维码图片,直接输出到OutputStream
        public static void encode(String content, String logoPath, OutputStream output)
                throws Exception {
            BufferedImage image = QrCodeUtil.createImage(content, logoPath);
            ImageIO.write(image, FORMAT, output);
        }
    
        //解析二维码图片,得到包含的内容
        public static String decode(String path) throws Exception {
            File file = new File(path);
            BufferedImage 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, UNICODE);
            result = new MultiFormatReader().decode(bitmap, hints);
            return result.getText();
        }
    }

    工具类,包含了生成二维码、保存二维码,展示二维码,解析二维码

    2,HomeController.java

    @RequestMapping("/home")
    @Controller
    public class HomeController {
        //生成带logo的二维码到response
        @RequestMapping("/qrcode")
        public void qrcode(HttpServletRequest request, HttpServletResponse response) {
            String requestUrl = "http://www.baidu.com";
            try {
                OutputStream os = response.getOutputStream();
                QrCodeUtil.encode(requestUrl, "/data/springboot2/logo.jpg", os);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //生成不带logo的二维码到response
        @RequestMapping("/qrnologo")
        public void qrnologo(HttpServletRequest request, HttpServletResponse response) {
            String requestUrl = "http://www.baidu.com";
            try {
                OutputStream os = response.getOutputStream();
                QrCodeUtil.encode(requestUrl, null, os);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //把二维码保存成文件
        @RequestMapping("/qrsave")
        @ResponseBody
        public String qrsave() {
            String requestUrl = "http://www.baidu.com";
            try {
                QrCodeUtil.save(requestUrl, "/data/springboot2/logo.jpg", "/data/springboot2/qrcode2.jpg");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "文件已保存";
        }
    
        //解析二维码中的文字
        @RequestMapping("/qrtext")
        @ResponseBody
        public String qrtext() {
            String url = "";
            try {
                 url = QrCodeUtil.decode("/data/springboot2/qrcode2.jpg");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "解析到的url:"+url;
        }
    }

    入口处包含了四个方法,接下来我们做测试

    五,测试效果

    1,生成不带logo的二维码,访问:

    http://127.0.0.1:8080/home/qrnologo

    效果:

    2,生成带logo的二维码:访问

    http://127.0.0.1:8080/home/qrcode

    效果:

    3,生成二维码保存成文件:访问:

    http://127.0.0.1:8080/home/qrsave

    代码中文件被保存成了:/data/springboot2/qrcode2.jpg

    4,解析二维码中包含的文字信息:访问:

    http://127.0.0.1:8080/home/qrtext

    返回:

    解析到的url:http://www.baidu.com

    成功解析到了图片中包含的url地址

    六,查看spring boot版本

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.2.RELEASE)
  • 相关阅读:
    【Python基础编程196 ● 文件/文件夹操作 ● 文件的操作步骤】
    【Python基础编程197 ● 文件/文件夹操作 ● 文件的访问模式】
    【Python基础编程199 ● 文件/文件夹操作 ● Python怎么读/写很大的文件】
    【Python基础编程198 ● 文件/文件夹操作 ● 读取文件的4种方式】
    【等待优化】如何定位网络性能问题 ASYNC_NETWORK_IO 等待
    (4.48)sql server添加列并使用默认值填充已有记录
    【sql server安全】sql server列加密查询性能问题及解决方案
    【sql server安全】sql server使用混合密钥实现列加密
    【sql server安全】sql server使用非对称秘钥实现列加密
    【sql server安全】sql server使用对称秘钥实现列加密
  • 原文地址:https://www.cnblogs.com/architectforest/p/13445821.html
Copyright © 2011-2022 走看看