Java 基于zxing生成二维码

依赖

        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.3</version>
        </dependency>

代码1

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;

// 二维码工具类
public class QRCodeUtil {
    public static final String FORMAT = "jpg"; // 二维码图片类型
    private static final String FONT_STR = "华文细黑"; // 字体
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 生成二维码(无logo)
     * @param width 二维码宽度
     * @param height 二维码高度
     * @param margin 二维码边距(白边宽度)
     * @param text 二维码内容
     * @param path 二维码保存路径
     * */
    public void generate(Integer width, Integer height, Integer margin, String text, String path){
        // 定义二维码的参数
        HashMap hashMap = new HashMap();
        // 设置二维码字符编码
        hashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 设置二维码纠错等级
        hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 设置二维码边距
        hashMap.put(EncodeHintType.MARGIN, margin);
        File qrFile = new File(path); // 二维码文件
        File qrParent = new File(qrFile.getParent()); // 文件父目录
        if(!qrParent.exists()) // 判断父目录是否存在
            qrParent.mkdirs(); // 不存在创建目录
        try {
            // 开始生成二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hashMap);
            // 导出到指定目录
            MatrixToImageWriter.writeToPath(bitMatrix, FORMAT,qrFile.toPath());
        } catch (WriterException e) {
            log.error("[二维码]生成二维码失败", e);
            e.printStackTrace();
        } catch (IOException e) {
            log.error("[二维码]生成二维码异常[path: " + path + "]", e);
            e.printStackTrace();
        }
    }

    /**
     * 生成二维码(带logo)
     * @param width 二维码宽度
     * @param height 二维码高度
     * @param margin 二维码边距(白边宽度)
     * @param text 二维码内容
     * @param path 二维码保存路径
     * @param logoPath logo图片路径
     * */
    public void generate(Integer width, Integer height, Integer margin, String text, String path, String logoPath){
        this.generate(width, height, margin, text, path);
        try {
            this.generateWithLogo(path, logoPath);
        } catch (IOException e) {
            log.error("[二维码]生成带logo的二维码异常[QRCode: " + path + ", logo: " + logoPath + "]", e);
            e.printStackTrace();
        }
    }

    /**
     * 生成二维码(带logo和文字描述)
     * @param size 二维码大小
     * @param text 二维码内容
     * @param path 二维码保存路径
     * @param logoPath logo图片路径
     * @param info  需要在二维码图片上添加的文字信息(并非二维码中的内容)
     * */
    public void generate(Integer size, String text, String path, String logoPath, String info){
        Integer width = size; // 二维码高度
        Integer fontSize = size / 25; // 字体
        Integer height = width; //高度
        this.generate(width, height, 3, text, path);
        try {
            this.generateWithLogo(path, logoPath);
            this.drawTextInImg(path, info, path, fontSize, FONT_STR);
        } catch (IOException e) {
            log.error("[二维码]生成带logo的二维码异常[QRCode: " + path + ", logo: " + logoPath + "]", e);
            e.printStackTrace();
        }
    }


    /**
     * 生成二维码(带文字描述无logo)
     * @param size 二维码大小 
     * @param text 二维码内容
     * @param path 二维码保存路径
     * @param info  需要在二维码图片上添加的文字信息(并非二维码中的内容)
     * */
    public void generate(Integer size, String text, String path, String info){
        Integer width = size; // 二维码高度
        Integer fontSize = size / 25; // 字体
        Integer height = width + fontSize * 2; //高度
        this.generate(width, height, 3, text, path);
        try {
            this.drawTextInImg(path, info, path, fontSize, FONT_STR);
        } catch (IOException e) {
            log.error("[二维码]添加文字描述异常[QRCodePath: " + path + "]", e);
            e.printStackTrace();
        }
    }


    /**
     * 生成带logo的二维码(圆角) 优化了绘制代码解决logo图失真的问题
     * @param path 二维码路径
     * @param logoPath logo图片路径
     * */
    private void generateWithLogo(String path, String logoPath) throws IOException{
        File file = new File(path);
        BufferedImage matrixImage = ImageIO.read(file);
        // 读取二维码图片,并构建绘图对象
        Graphics2D g2 = matrixImage.createGraphics();
        int matrixWidth = matrixImage.getWidth();
        int matrixHeigh = matrixImage.getHeight();
        // 读取Logo图片
        BufferedImage logo = ImageIO.read(new File(logoPath));
        // 开始绘制图片
        g2.drawImage(logo.getScaledInstance(matrixWidth/5, matrixWidth/5, Image.SCALE_SMOOTH),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.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 消除锯齿
        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();
        logo.flush();
        matrixImage.flush() ;
        ImageIO.write(matrixImage, FORMAT, file); // 保存图片
    }

    /**
     * 生成带logo的二维码(方块)
     * @param path 二维码路径
     * @param logoPath logo图片路径
     * */
    private void generateWithCubeLogo(String path, String logoPath) throws IOException {
        BufferedImage i = ImageIO.read(new File(path));
        Integer qrWidth = i.getWidth();
        Integer qrHeight = i.getHeight();
        BufferedImage image = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_RGB);
        // 开始利用二维码数据创建Bitmap图片
        for (int x = 0; x < qrWidth; x++) {
            for (int y = 0; y < qrHeight; y++) {
                image.setRGB(x, y, i.getRGB(x, y));
            }
        }
        int width = image.getWidth();
        int height = image.getHeight();
        // 构建绘图对象
        Graphics2D g = image.createGraphics();
        // 读取Logo图片
        BufferedImage logo = ImageIO.read(new File(logoPath));
        // 开始绘制logo图片
        g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
        g.dispose();
        logo.flush();
        ImageIO.write(image, "jpg", new File(path));
    }

    /**
     * 图片中添加文字
     * @param filePath 图片路径
     * @param text 需要添加的文字
     * @param outPath 添加完后文件保存的路径
     * @param fontSize 文字字体大小
     * @param fontStr 文字字体
     * */
    private void drawTextInImg(String filePath, String text, String outPath,int fontSize, String fontStr) throws IOException {
        BufferedImage img = ImageIO.read(new File(filePath));
        int width = img.getWidth();
        int height = img.getHeight();
        BufferedImage bimage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        Integer n = text.replaceAll("[\\u4e00-\\u9fa5]", "aa").length();
        Graphics2D g = bimage.createGraphics();
        int rectX = (img.getWidth() - fontSize * n / 2) / 2;
        int rectY = img.getHeight() - fontSize;
        Font font = new Font(fontStr, Font.PLAIN, fontSize);   //定义字体
        g.setBackground(Color.white);
        g.drawImage(img, 0, 0, null);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 消除锯齿
        g.setPaint(Color.black);
        g.setFont(font);
        g.drawString(text, rectX, rectY);
        g.dispose();
        try {
            ImageIO.write(bimage, "jpg", new File(outPath));
        } catch (FileNotFoundException e) {
            log.error("[二维码]添加文字描述时找不到指定路径【path: " + outPath + "】", e);
            e.printStackTrace();
        } catch (IOException e) {
            log.error("[二维码]添加文字描述时IO异常【path: " + outPath + "】", e);
            e.printStackTrace();
        }
        bimage.flush();
    }
}

代码2

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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.util.HashMap;

// 二维码工具类
public class QRCodeUtil {
    private static final String FONT_STR = "华文细黑"; // 字体
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 生成二维码(无logo)
     * @param width 二维码宽度
     * @param height 二维码高度
     * @param margin 二维码边距(白边宽度)
     * @param text 二维码内容
     * @return BufferedImage
     * */
    public BufferedImage generate(Integer width, Integer height, Integer margin, String text){
           return this.generateQRCode(width, height, margin, text);
    }

    /**
     * 生成二维码(带logo)
     * @param width 二维码宽度
     * @param height 二维码高度
     * @param margin 二维码边距(白边宽度)
     * @param text 二维码内容
     * @param logoPath logo图片路径
     * @return BufferedImage
     * */
    public BufferedImage generate(Integer width, Integer height, Integer margin, String text, String logoPath){
        BufferedImage qrCode = this.generateQRCode(width, height, margin, text);
        try {
            this.addLogoImage(qrCode, logoPath);
            return qrCode;
        } catch (IOException e) {
            log.error(" [二维码]logo图片异常,path: " + logoPath, e);
        }
        throw new RuntimeException("二维码生成失败");
    }

    /**
     * 生成二维码(带logo和文字描述)
     * @param size 二维码大小
     * @param text 二维码内容
     * @param logoPath logo图片路径
     * @param info  需要在二维码图片上添加的文字信息(并非二维码中的内容)
     * @return BufferedImage
     * */
    public BufferedImage generate(Integer size, String text, String logoPath, String info){
        BufferedImage qrCode = this.generateQRCode(size, size, 3, text);
        try {
            this.addLogoImage(qrCode, logoPath);
            this.addText(qrCode, info, size / 25, FONT_STR);
            return qrCode;
        } catch (IOException e) {
            log.error(" [二维码]logo图片异常,path: " + logoPath, e);
        }
        throw new RuntimeException("二维码生成失败");
    }


    /**
     * 生成二维码(带文字描述无logo)
     * @param size 二维码大小
     * @param text 二维码内容
     * @param info  需要在二维码图片上添加的文字信息(并非二维码中的内容)
     * */
    public BufferedImage generate(Integer size, String text, String info){
        BufferedImage qrCode = this.generateQRCode(size, size, 3, text);
        this.addText(qrCode, info, size / 25, FONT_STR);
        return qrCode;
    }


    /**
     * 生成二维码图片
     * @param width  二维码宽度
     * @param height 二维码高度
     * @param margin 二维码边距(白边宽度)
     * @param text   二维码内容
     * @return BufferedImage
     */
    private BufferedImage generateQRCode(Integer width, Integer height, Integer margin, String text){
        // 定义二维码的参数
        HashMap hashMap = new HashMap();
        // 设置二维码字符编码
        hashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 设置二维码纠错等级
        hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 设置二维码边距
        hashMap.put(EncodeHintType.MARGIN, margin);
        try {
            // 开始生成二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hashMap);
            // 创建BufferedImage将二维码图片绘制到里面, MatrixToImageWriter.toBufferedImage方法返回的BufferedImag.Type为TYPE_BYTE_BINARY,既只有黑白两种颜色
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
            bufferedImage.getGraphics().drawImage(MatrixToImageWriter.toBufferedImage(bitMatrix), 0, 0, null);
            return bufferedImage;
        } catch (WriterException e) {
            log.error("[二维码]生成二维码失败", e);
        }
        log.error("[二维码]生成二维码失败");
        throw new RuntimeException("二维码生成失败");
    }

    /**
     * 在二维码中间添加logo图片
     * @param matrixImage 二维码图片 BufferedImage
     * @param logoPath logo图片路径
     * @return BufferedImage
     * */
    private void addLogoImage(BufferedImage matrixImage, String logoPath) throws IOException {
        // 读取二维码图片,并构建绘图对象
        Graphics2D g2 = matrixImage.createGraphics();
        int matrixWidth = matrixImage.getWidth();
        int matrixHeigh = matrixImage.getHeight();
        // 读取Logo图片
        BufferedImage logo = ImageIO.read(new File(logoPath));
        // 开始绘制图片
        g2.drawImage(logo.getScaledInstance(matrixWidth/5, matrixWidth/5, Image.SCALE_SMOOTH),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.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 消除锯齿
        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();
        logo.flush();
        matrixImage.flush();
    }

    /**
     * 图片中添加文字
     * @param matrixImage 二维码图片 BufferedImage
     * @param text 需要添加的文字
     * @param fontSize 文字字体大小
     * @param fontStr 文字字体
     * */
    private void addText(BufferedImage matrixImage, String text, int fontSize, String fontStr){
        Integer n = text.replaceAll("[\\u4e00-\\u9fa5]", "aa").length();
        Graphics2D g = matrixImage.createGraphics();
        int rectX = (matrixImage.getWidth() - fontSize * n / 2) / 2;
        int rectY = matrixImage.getHeight() - fontSize;
        Font font = new Font(fontStr, Font.PLAIN, fontSize);   //定义字体
        g.setBackground(Color.red);
        g.drawImage(matrixImage, 0, 0, null);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 消除锯齿
        g.setPaint(Color.black);
        g.setFont(font);
        g.drawString(text, rectX, rectY);
        g.dispose();
        matrixImage.flush();
    }

}

效果图

在这里插入图片描述

要使用Java生成二维码,你可以依赖Google的zxing类库。这个类库提供了二维码生成的策略,你只需要调用它的API来生成二维码对象。首先,你需要准备以下信息:字符串内容、二维码的宽度和高度、字符集、颜色、外边距和纠错等级等。在zxing包中的MultiFormatWriter类是生成二维码的核心工具类,你可以使用它的encode方法将要封装的字符串内容转化为二维码对象。 以下是生成二维码的步骤: 步骤1:导入zxing类库,并创建MultiFormatWriter对象。 步骤2:创建一个Map集合,用于存储参数,包括字符集和二维码类型。 步骤3:调用MultiFormatWriter对象的encode方法,传入字符串内容和参数Map,将其转化为二维码对象。 步骤4:将二维码对象写入磁盘或输出流,以保存或展示二维码。 下面是一个简单的Java代码示例,演示了如何使用zxing生成二维码: ``` import com.google.zxing.BarcodeFormat; import com.google.zxing.MultiFormatWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class QRCodeGenerator { public static void main(String[] args) { String content = "Hello, World!"; // 二维码内容 int width = 300; // 二维码宽度 int height = 300; // 二维码高度 String charset = "UTF-8"; // 字符集 // 设置参数 Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, charset); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 纠错等级为高 try { // 生成二维码 BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); // 创建BufferedImage对象,并设置颜色模式 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); image.createGraphics(); // 设置二维码颜色 Graphics2D graphics = (Graphics2D) image.getGraphics(); graphics.setColor(Color.WHITE); graphics.fillRect(0, 0, width, height); graphics.setColor(Color.BLACK); // 绘制二维码 for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (matrix.get(i, j)) { graphics.fillRect(i, j, 1, 1); } } } // 保存二维码到磁盘 ImageIO.write(image, "png", new File("qrcode.png")); System.out.println("二维码已生成并保存到qrcode.png文件中。"); } catch (Exception e) { e.printStackTrace(); } } } ``` 这段代码将生成一个内容为"Hello, World!"的二维码,并保存到名为qrcode.png的文件中。你可以根据自己的需求调整代码中的参数,来生成不同样式的二维码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Java利用zxing生成二维码](https://blog.csdn.net/qq_43598138/article/details/105444641)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Java利用Zxing生成二维码的简单实例](https://download.csdn.net/download/weixin_38598703/12794633)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值