二维码的JAVA实现

生成二维码的过程可以通过 Java 中的第三方库来实现,其中最常用的是Zxing库。以下是使用Zxing库生成二维码的简要步骤:

首先引入相关的依赖

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

接着编写对应的工具类来辅助生成二维码

  1. 首先是一些静态常量的定义,包括二维码的宽度、高度、前景色和背景色等。

  2.  //CODE_WIDTH:二维码宽度,单位像素
        private static final int CODE_WIDTH = 400;
        //CODE_HEIGHT:二维码高度,单位像素
        private static final int CODE_HEIGHT = 400;
        //FRONT_COLOR:二维码前景色,0x000000 表示黑色
        private static final int FRONT_COLOR = 0x000000;
        //BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色
        //演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白
        private static final int BACKGROUND_COLOR = 0xFFFFFF;

  3. createCodeToFile 方法用于将生成的二维码保存到文件中。它接受三个参数:content 表示要编码的内容,codeImgFileSaveDir 表示保存目录,fileName 表示文件名。在方法内部,首先对参数进行检查,如果内容或文件名为空,则直接返回;然后对保存目录进行判断,如果不存在则创建。接着调用核心方法 getBufferedImage 生成二维码的 BufferedImage 对象,并将其写入到指定的文件中。

  4.     public static void createCodeToFile(String content, File codeImgFileSaveDir, String fileName) {
            try {
                if (StringUtils.isBlank(content) || StringUtils.isBlank(fileName)) {
                    return;
                }
               content = content.trim();
                if (codeImgFileSaveDir==null || codeImgFileSaveDir.isFile()) {
                    //二维码图片存在目录为空,默认放在桌面...
                    codeImgFileSaveDir = FileSystemView.getFileSystemView().getHomeDirectory();
                }
                if (!codeImgFileSaveDir.exists()) {
                    //二维码图片存在目录不存在,开始创建...
                    codeImgFileSaveDir.mkdirs();
                }
     
                //核心代码-生成二维码
                BufferedImage bufferedImage = getBufferedImage(content);
     
                File codeImgFile = new File(codeImgFileSaveDir, fileName);
                ImageIO.write(bufferedImage, "png", codeImgFile);
     
    //            log.info("二维码图片生成成功:" + codeImgFile.getPath());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

  5. createCodeToOutputStream 方法用于将生成的二维码输出到输出流中,通常用于在网页上显示二维码。它接受两个参数:content 表示要编码的内容,outputStream 表示输出流。在方法内部,同样先对 content 进行检查,然后调用核心方法 getBufferedImage 生成二维码的 BufferedImage 对象,并将其写入到输出流中。

  6.     /**
         * 生成二维码并输出到输出流, 通常用于输出到网页上进行显示,输出到网页与输出到磁盘上的文件中,区别在于最后一句 ImageIO.write
         * write(RenderedImage im,String formatName,File output):写到文件中
         * write(RenderedImage im,String formatName,OutputStream output):输出到输出流中
         * @param content  :二维码内容
         * @param outputStream :输出流,比如 HttpServletResponse 的 getOutputStream
         */
        public static void createCodeToOutputStream(String content, OutputStream outputStream) {
            try {
                if (StringUtils.isBlank(content)) {
                    return;
                }
                content = content.trim();
                //核心代码-生成二维码
                BufferedImage bufferedImage = getBufferedImage(content);
     
                //区别就是这一句,输出到输出流中,如果第三个参数是 File,则输出到文件中
                ImageIO.write(bufferedImage, "png", outputStream);
     
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     

  7. getBufferedImage 方法是生成二维码的核心代码。它接受内容作为参数,使用 com.google.zxing 库来生成二维码。在方法内部,首先创建一个 Map 类型的对象 hints,用于存放编码时的一些提示信息,比如字符编码类型、误差校正等级、边距等。然后使用 MultiFormatWriterencode 方法生成二维码的 BitMatrix 对象,再根据 BitMatrix 对象的值来设置 BufferedImage 的像素值,从而生成最终的二维码图片。

  8.   //核心代码-生成二维码
        private static BufferedImage getBufferedImage(String content) throws WriterException {
     
            //com.google.zxing.EncodeHintType:编码提示类型,枚举类型
            Map<EncodeHintType, Object> hints = new HashMap();
     
            //EncodeHintType.CHARACTER_SET:设置字符编码类型
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
     
            //EncodeHintType.ERROR_CORRECTION:设置误差校正
            //ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
            //不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
     
            //EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
            hints.put(EncodeHintType.MARGIN, 1);
            
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
            BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
            for (int x = 0; x < CODE_WIDTH; x++) {
                for (int y = 0; y < CODE_HEIGHT; y++) {
                    bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
                }
            }
            return bufferedImage;
        }

    完整的如下

    package com.ruoyi.util;
    
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.WriterException;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    import com.ruoyi.common.utils.StringUtils;
    import org.mybatis.logging.LoggerFactory;
    
    import javax.imageio.ImageIO;
    import javax.swing.filechooser.FileSystemView;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.OutputStream;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.logging.Logger;
    
    public class QRCodeUtil {
      //  private static final Logger log= LoggerFactory.getLogger(QRCodeUtil.class);
        //CODE_WIDTH:二维码宽度,单位像素
        private static final int CODE_WIDTH = 400;
        //CODE_HEIGHT:二维码高度,单位像素
        private static final int CODE_HEIGHT = 400;
        //FRONT_COLOR:二维码前景色,0x000000 表示黑色
        private static final int FRONT_COLOR = 0x000000;
        //BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色
        //演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白
        private static final int BACKGROUND_COLOR = 0xFFFFFF;
     
        public static void createCodeToFile(String content, File codeImgFileSaveDir, String fileName) {
            try {
                if (StringUtils.isBlank(content) || StringUtils.isBlank(fileName)) {
                    return;
                }
               content = content.trim();
                if (codeImgFileSaveDir==null || codeImgFileSaveDir.isFile()) {
                    //二维码图片存在目录为空,默认放在桌面...
                    codeImgFileSaveDir = FileSystemView.getFileSystemView().getHomeDirectory();
                }
                if (!codeImgFileSaveDir.exists()) {
                    //二维码图片存在目录不存在,开始创建...
                    codeImgFileSaveDir.mkdirs();
                }
     
                //核心代码-生成二维码
                BufferedImage bufferedImage = getBufferedImage(content);
     
                File codeImgFile = new File(codeImgFileSaveDir, fileName);
                ImageIO.write(bufferedImage, "png", codeImgFile);
     
    //            log.info("二维码图片生成成功:" + codeImgFile.getPath());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
        /**
         * 生成二维码并输出到输出流, 通常用于输出到网页上进行显示,输出到网页与输出到磁盘上的文件中,区别在于最后一句 ImageIO.write
         * write(RenderedImage im,String formatName,File output):写到文件中
         * write(RenderedImage im,String formatName,OutputStream output):输出到输出流中
         * @param content  :二维码内容
         * @param outputStream :输出流,比如 HttpServletResponse 的 getOutputStream
         */
        public static void createCodeToOutputStream(String content, OutputStream outputStream) {
            try {
                if (StringUtils.isBlank(content)) {
                    return;
                }
                content = content.trim();
                //核心代码-生成二维码
                BufferedImage bufferedImage = getBufferedImage(content);
     
                //区别就是这一句,输出到输出流中,如果第三个参数是 File,则输出到文件中
                ImageIO.write(bufferedImage, "png", outputStream);
     
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
        //核心代码-生成二维码
        private static BufferedImage getBufferedImage(String content) throws WriterException {
     
            //com.google.zxing.EncodeHintType:编码提示类型,枚举类型
            Map<EncodeHintType, Object> hints = new HashMap();
     
            //EncodeHintType.CHARACTER_SET:设置字符编码类型
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
     
            //EncodeHintType.ERROR_CORRECTION:设置误差校正
            //ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
            //不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
     
            //EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
            hints.put(EncodeHintType.MARGIN, 1);
            
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
            BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
            for (int x = 0; x < CODE_WIDTH; x++) {
                for (int y = 0; y < CODE_HEIGHT; y++) {
                    bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
                }
            }
            return bufferedImage;
        }
    }
    

    在有了工具类后就可以进行二维码的生成了,这里需要注意到的是,一般对于二维码的内容展示,其主要为在创建二维码的同时,将网址进行塞入到二维码中,据此实现扫描二维码而访问系统的内部页面进行页面的展示。

这里根据上文就可以清除,对于生成到二维码主要有两种处理方式,将二维码进行生成后存储到数据库中。第二种则是将二维码生成后直接作为输出流返回给前端,前端进行渲染实现直接扫描。

第一种实现为:

该方法的content为一个网址,扫描二维码主要展示的是该网址的内容

方法实现后,会将该二维码生成并且存到指定路径上,接着将该路径进行返回,进行存储查看等内容。

    public static String generateV1(String content) {
        try {
            final String fileName = LOCALDATEFORMAT.get().format(new Date());
            QRCodeUtil.createCodeToFile(content, new File(RootPath), fileName + FileFormat);
            return "/profile/" + fileName + FileFormat;
        } catch (Exception e) {
            return "二维码异常";
        }

    }

从service调用实现的内容为

  @Override
    public int insertHospitalEquipmentPlan(HospitalEquipmentPlan hospitalEquipmentPlan)
    {
        long l = new Random().nextInt(2000);
        hospitalEquipmentPlan.setId(l);
        String ss = QrCodeController.generateV1("http://192.xx.x.xx:8088/qx.html?op="+hospitalEquipmentPlan.getId());
        hospitalEquipmentPlan.setQr_code(ss);
        return hospitalEquipmentPlanMapper.insertHospitalEquipmentPlan(hospitalEquipmentPlan);
    }

此处的业务为新建一条医院记录的时候,同时将该器械消毒的二维码生成,通过随机生成id并调用generateV1方法,往其中塞入扫描二维码后的网址,返回该二维码的路径,协同其他数据共同保存

第二种实现为:

该内容为直接通过输出流进行返回,前端可直接进行展示。

   //生成二维码并将其返回给前端调用者
    @PostMapping("/v2")
    public AjaxResult generateV2(String content, HttpServletResponse servletResponse) {

        try {
            QRCodeUtil.createCodeToOutputStream(content, servletResponse.getOutputStream());

        } catch (Exception e) {
            return AjaxResult.error("二维码失败");
        }
        return AjaxResult.success();
    }

生成二维码可以使用Java的ZXing库来实现。下面是一个简单的示例代码,使用ZXing生成二维码并保存为图片文件: ```java import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; public class QRCodeGenerator { public static void main(String[] args) { String text = "https://www.example.com/"; // 二维码内容 int width = 300; // 二维码宽度 int height = 300; // 二维码高度 String format = "png"; // 二维码格式 try { // 设置编码参数 java.util.Map<EncodeHintType, Object> hints = new java.util.HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 生成二维码 QRCodeWriter writer = new QRCodeWriter(); BitMatrix bitMatrix = writer.encode(text, BarcodeFormat.QR_CODE, width, height, hints); 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); } } // 保存二维码为图片文件 File outputFile = new File("qrcode.png"); ImageIO.write(image, format, outputFile); } catch (WriterException | IOException e) { e.printStackTrace(); } } } ``` 在以上代码中,我们使用QRCodeWriter类生成二维码的BitMatrix对象,然后将其转换为BufferedImage对象,并保存为PNG格式的图片文件。你可以根据自己的需求调整代码中的参数和输出格式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值