• Google zxing 生成带logo的二维码图片


    环境准备

    添加maven配置

    <dependency>
        <groupId>com.google.zxinggroupId>
        <artifactId>coreartifactId>
        <version>3.4.0version>
    dependency>
    <dependency>
        <groupId>com.google.zxinggroupId>
        <artifactId>javaseartifactId>
        <version>3.4.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建比特矩阵

    先创建比特矩阵,设置默认的宽度、高度、后缀名等等

     private static final String DEFAULT_CHAR_SET = "UTF-8";
    
    private static final String DEFAULT_FORMAT_NAME = "JPG";
    
    
    // 二维码宽度
    private static final int DEFAULT_QR_CODE_WIDTH = 300;
    // 二维码高度
    private static final int DEFAULT_QR_CODE_HEIGHT = 300;
    
    /**
     * 创建BitMatrix比特矩阵
     * @Date 2023/09/24 22:29
     * @Param contents 二维码里的内容
     * @Param width 二维码宽度
     * @param height 二维码高度
     * @return com.google.zxing.common.BitMatrix
     */
    public static  BitMatrix createBitMatrix(String contents , int width , int height) throws WriterException, IOException {
        if (ObjectUtil.isNull(width)) {
            width = DEFAULT_QR_CODE_WIDTH;
        }
        if (ObjectUtil.isNull(height)) {
            height = DEFAULT_QR_CODE_HEIGHT;
        }
    
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 纠错等级L,M,Q,H
        hints.put(EncodeHintType.CHARACTER_SET, DEFAULT_CHAR_SET);// 编码utf-8
        hints.put(EncodeHintType.MARGIN, 1);  // 边距
    
        // 创建比特矩阵
        BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
                BarcodeFormat.QR_CODE, width, height, hints);
        return bitMatrix;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    转换为BufferedImage

    创建好比特矩阵后,转换为BufferedImage

     /**
     * 转换为BufferedImage
     * @Date 2023/09/24 22:32
     * @Param [bitMatrix]
     * @return java.awt.image.BufferedImage
     */
    public static BufferedImage toBufferedImage(BitMatrix bitMatrix) throws IOException, WriterException {
        MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig);
        return bufferedImage;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    加上二维码logo

    给创建的二维码BufferedImage加上logo

     /**
     * 给二维码添加logo
      * @Date 2023/09/24 22:33
      * @Param [bufferedImage, logoFile]
      * @return java.awt.image.BufferedImage
      */
     public static BufferedImage addQrCodeLogo(BufferedImage bufferedImage, File logoFile) throws IOException {
         Graphics2D graphics = bufferedImage.createGraphics();
         int matrixWidth = bufferedImage.getWidth();
         int matrixHeigh = bufferedImage.getHeight();
    
         // 读取logo图片文件
         BufferedImage logo = ImageIO.read(logoFile);
         int logoWidth = logo.getWidth();
         int logoHeight = logo.getHeight();
    
         //  计算logo放置位置
         int x = bufferedImage.getWidth()  / 5*2;
         int y = bufferedImage.getHeight() / 5*2;
         int width = matrixWidth / 5;
         int height = matrixHeigh / 5;
    
         // 开始绘制图片
         graphics.drawImage(logo, x, y, width, height, null);
         graphics.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15);
         graphics.setStroke(new BasicStroke(5.0F, 1, 1));
         graphics.setColor(Color.white);
         graphics.drawRect(x, y, logoWidth, logoHeight);
    
         graphics.dispose();
         bufferedImage.flush();
         return bufferedImage;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    测试

    public static void main(String[] args) throws Exception {
         BufferedImage bufferedImage = toBufferedImage(createBitMatrix("https://blog.csdn.net", 300, 300));
         ImageIO.write(bufferedImage, "png", new File("D:/qrcode.jpg"));
    
         System.out.println(decodeQrCode(bufferedImage));
    
         BufferedImage logoQrCode = addQrCodeLogo(bufferedImage, new File("D://logo.png"));
         ImageIO.write(logoQrCode, "png", new File("D:/logoQrcode.jpg"));
     }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建不带logo的二维码图片
    在这里插入图片描述
    创建带logo的二维码图片
    在这里插入图片描述

    附录

    package com.example.common.util.qrcode;
    
    
    import cn.hutool.core.codec.Base64;
    import cn.hutool.core.util.ObjectUtil;
    import cn.hutool.core.util.StrUtil;
    import com.google.zxing.*;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.client.j2se.MatrixToImageConfig;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    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.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.util.Hashtable;
    
    public class QrCodeGenerator {
    
    
        private static final String DEFAULT_CHAR_SET = "UTF-8";
    
        private static final String DEFAULT_FORMAT_NAME = "JPG";
    
    
        // 二维码宽度
        private static final int DEFAULT_QR_CODE_WIDTH = 300;
        // 二维码高度
        private static final int DEFAULT_QR_CODE_HEIGHT = 300;
    
        /**
         * 创建BitMatrix比特矩阵
         * @Date 2023/09/24 22:29
         * @Param contents 二维码里的内容
         * @Param width 二维码宽度
         * @param height 二维码高度
         * @return com.google.zxing.common.BitMatrix
         */
        public static  BitMatrix createBitMatrix(String contents , int width , int height) throws WriterException, IOException {
            if (ObjectUtil.isNull(width)) {
                width = DEFAULT_QR_CODE_WIDTH;
            }
            if (ObjectUtil.isNull(height)) {
                height = DEFAULT_QR_CODE_HEIGHT;
            }
    
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 纠错等级L,M,Q,H
            hints.put(EncodeHintType.CHARACTER_SET, DEFAULT_CHAR_SET);// 编码utf-8
            hints.put(EncodeHintType.MARGIN, 1);  // 边距
    
            // 创建比特矩阵
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
                    BarcodeFormat.QR_CODE, width, height, hints);
            return bitMatrix;
    
        }
    
        /**
         * 创建二维码,返回字节数组
         * @Date 2023/09/24 22:30
         * @Param contents 二维码里的内容
         * @Param imageFormat 图片后缀名
         * @Param width 二维码宽度
         * @param height 二维码高度
         * @return byte[]
         */
        public static byte[] createQrCode(String contents , String imageFormat , int width , int height) throws WriterException, IOException {
            if (StrUtil.isBlank(imageFormat)){
                imageFormat = DEFAULT_FORMAT_NAME;
            }
            BitMatrix bitMatrix = createBitMatrix(contents , width, height);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, os);
            return os.toByteArray();
        }
    
        /**
         * 创建二维码,返回base64字符串
         * @Date 2023/09/24 22:30
         * @Param contents 二维码里的内容
         * @Param imageFormat 图片后缀名
         * @Param width 二维码宽度
         * @param height 二维码高度
         * @return byte[]
         */
        public static String createQrCodeBase64(String contents , String imageFormat , int width , int height) throws WriterException, IOException {
            byte[] bytes =createQrCode(contents , imageFormat , width, height);
            return Base64.encode(bytes);
        }
    
        /**
         * 解码二维码
         * @Date 2023/09/24 22:32
         * @Param [image]
         * @return java.lang.String
         */
        public static String decodeQrCode(BufferedImage image) throws Exception {
            if (image == null) return StrUtil.EMPTY;
            BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, DEFAULT_CHAR_SET);
            Result result = new MultiFormatReader().decode(bitmap, hints);
            return result.getText();
        }
    
        /**
         * 转换为BufferedImage
         * @Date 2023/09/24 22:32
         * @Param [bitMatrix]
         * @return java.awt.image.BufferedImage
         */
        public static BufferedImage toBufferedImage(BitMatrix bitMatrix) throws IOException, WriterException {
            MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig);
            return bufferedImage;
        }
    
        /**
         * 给二维码添加logo
         * @Date 2023/09/24 22:33
         * @Param [bufferedImage, logoFile]
         * @return java.awt.image.BufferedImage
         */
        public static BufferedImage addQrCodeLogo(BufferedImage bufferedImage, File logoFile) throws IOException {
            Graphics2D graphics = bufferedImage.createGraphics();
            int matrixWidth = bufferedImage.getWidth();
            int matrixHeigh = bufferedImage.getHeight();
    
            // 读取logo图片文件
            BufferedImage logo = ImageIO.read(logoFile);
            int logoWidth = logo.getWidth();
            int logoHeight = logo.getHeight();
    
            //  计算logo放置位置
            int x = bufferedImage.getWidth()  / 5*2;
            int y = bufferedImage.getHeight() / 5*2;
            int width = matrixWidth / 5;
            int height = matrixHeigh / 5;
    
            // 开始绘制图片
            graphics.drawImage(logo, x, y, width, height, null);
            graphics.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15);
            graphics.setStroke(new BasicStroke(5.0F, 1, 1));
            graphics.setColor(Color.white);
            graphics.drawRect(x, y, logoWidth, logoHeight);
    
            graphics.dispose();
            bufferedImage.flush();
            return bufferedImage;
        }
    
        public static void main(String[] args) throws Exception {
            BufferedImage bufferedImage = toBufferedImage(createBitMatrix("https://blog.csdn.net", 300, 300));
            ImageIO.write(bufferedImage, "png", new File("D:/qrcode.jpg"));
    
            System.out.println(decodeQrCode(bufferedImage));
    
            BufferedImage logoQrCode = addQrCodeLogo(bufferedImage, new File("D://logo.png"));
            ImageIO.write(logoQrCode, "png", new File("D:/logoQrcode.jpg"));
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
  • 相关阅读:
    Mybatis入门实战
    随便给你一个页面 你该如何去给他布局呢 各位思考一下 ?
    vivado报错警告之[Vivado 12-1017] Problems encountered:
    【重识云原生】第六章容器基础6.4.9.4节——Service拓扑感知提示
    React UI组件库——如何快速实现antd的按需引入和自定义主题
    webpack5从零开始,到打包一个项目的基本配置
    Python 关键字 yield
    【路径规划】基于状态空间采样实现机器人二维路径规划附matlab完整代码
    每日学习(1)
    【Java】集合 之 Java集合简介
  • 原文地址:https://blog.csdn.net/u014427391/article/details/133255353