SpringBoot整合ZXing创建二维码和条形码

文章目录

  • 1、引入依赖
  • 2、Service层实现
  • 3、Controller
  • 4、效果

之前SpringSecurity时,登录用到了图片验证码辅助登录:【 整合hutool实现集成图片验证码】,以下为整合zxing实现二维码和条形码的生成。

1、引入依赖

引入ZXing依赖的坐标:

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

2、Service层实现

Service接口略,实现类:

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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

/**
 * @author LLG
 * @date 2023/12/8
 */
@Service
@Slf4j
public class CodeService {

    /**
     * 生成二维码
     * @param data   扫描二维码后得到的信息
     * @param width  二维码的宽
     * @param height 二维码的高
     * @return image
     */
    public BufferedImage generateCode(String data, int width, int height) {
        BufferedImage image = null;
        try {
            Map<EncodeHintType, Object> hints = new HashMap<>();
            //字符编码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            //错误纠正级别
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            //二维码边距
            hints.put(EncodeHintType.MARGIN, 2);
            MultiFormatWriter writer = new MultiFormatWriter();
            //样式选择QR_CODE,其余枚举类中的可选样式可自己玩
            BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.QR_CODE, width, height, hints);
            image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            //每个框框的颜色
            for (int i = 0; i < width; i++) {
                for (int j = 0; j < height; j++) {
                    image.setRGB(i, j, bitMatrix.get(i, j) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
                }
            }
            /*以下为选择保存二维码
            String filePath = "test.png";
            File codeFile = new File(filePath);
            ImageIO.write(image,"png",codeFile);
            log.info("QR码生成成功,保存路径{}",filePath);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;

    }

    /**
     * 生成条形码
     * @param data   扫描二维码后得到的信息
     * @param width  条形码的宽
     * @param height 条形码的高
     * @return image
     */
    public BufferedImage generateBarCode(String data, int width, int height) {
        BufferedImage image = null;
        try {
            Map<EncodeHintType, Object> hints = new HashMap<>();
            //字符编码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            MultiFormatWriter writer = new MultiFormatWriter();
            //码的样式这次选CODE_128
            BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.CODE_128, width, height, hints);
            image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            for (int i = 0; i < width; i++) {
                for (int j = 0; j < height; j++) {
                    image.setRGB(i, j, bitMatrix.get(i, j) ? 0 : 0xFFFFFF);   //黑白条形码
                }
            }
        } catch (WriterException e) {
            e.printStackTrace();
        }

        return image;
    }

 
}

3、Controller

写个简单API调用下:

@RestController
public class CodeController {

    @Resource
    private CodeService codeService;

    @GetMapping("/code/image")
    public void getCodeImage(HttpServletRequest request, HttpServletResponse response){
        //测试数据
        String data = "code9527-test!";
        BufferedImage image = codeService.generateCode(data, 100, 100);
        try {
            ImageIO.write(image,"png",response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/code/barCode")
    public void getBarCode(HttpServletRequest request,HttpServletResponse response){
        //条形码中的内容
        String data = "TB20231208154900";
        BufferedImage barCode = codeService.generateBarCode(data, 400, 100);
        try {
            ImageIO.write(barCode,"png",response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4、效果

二维码:

在这里插入图片描述

条形码:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/235209.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索未来新趋势:鸿蒙系统的崭新时代

探索未来新趋势&#xff1a;鸿蒙系统的崭新时代 随着科技的不断发展&#xff0c;操作系统作为计算机和移动设备的核心&#xff0c;扮演着至关重要的角色。近年来&#xff0c;一种备受瞩目的操作系统——鸿蒙系统&#xff08;HarmonyOS&#xff09;崭露头角&#xff0c;正引领着…

Servlet学习笔记

简介 浏览器请求处理流程&#xff1a;浏览器发请求 > 服务器tomcat( > 应用程序 ( > servlet) ) Servlet应用的三大作用域&#xff1a;request&#xff0c;session&#xff0c;application tomcat存放项目的层级结构 注释&#xff1a;servlet原引用包名 javax.serv…

城市道路积水如何有效预警?内涝积水监测仪效果

在城市中道路积水是一个常见的问题&#xff0c;特别是在暴雨季节还可能形成城市内涝。为了解决这个问题建立一个有效的预警系统是至关重要的。城市内涝积水监测仪应该能够实时监测道路积水情况&#xff0c;并及时向后台工作人员发出警报&#xff0c;以便他们能够采取适当的措施…

mysql中的DQL查询

表格为&#xff1a; DQL 基础查询 语法&#xff1a;select 查询列表 from 表名&#xff1a;&#xff08;查询的结果是一个虚拟表格&#xff09; -- 查询指定的列 SELECT NAME,birthday,phone FROM student -- 查询所有的列 * 所有的列&#xff0c; 查询结果是虚拟的表格&am…

【Spring教程23】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC简介与SpringMVC概述

目录 1&#xff0c;SpringMVC简介2、SpringMVC概述 欢迎大家回到《Java教程之Spring30天快速入门》&#xff0c;本教程所有示例均基于Maven实现&#xff0c;如果您对Maven还很陌生&#xff0c;请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》&…

LANDSAT_7/02/T1/RAW的Landsat7_C2_RAW类数据集

Landsat7_C2_RAW是指Landsat 7卫星的数据集&#xff0c;采用的是Collection 2级别的数据处理方法&#xff0c;对应的是Tier 1级别的原始数据&#xff08;RAW&#xff09;。该数据集包括了Landsat 7卫星从1999年4月15日开始的所有数据&#xff0c;共涵盖了全球范围内的陆地和海洋…

【开源】基于Vue和SpringBoot的森林火灾预警系统

项目编号&#xff1a; S 019 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S019&#xff0c;文末获取源码。} 项目编号&#xff1a;S019&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 系统基础模块2.3 烟…

Aligning Large Multi-Modal Model with Robust Instruction Tuning

Abstract 尽管多模态任务取得了有希望的进展&#xff0c;但当前的大型多模态模型&#xff08;LMM&#xff09;很容易产生与相关图像和人类指令 不一致的描述的幻觉。 LRV-指令。我们通过引入第一个大型且多样化的视觉指令调整数据集来解决这个问题&#xff0c;该数据集名为大…

【项目实现】ResShift:通过残差位移实现图像超分辨率的高效扩散模型(NeurIPS 2023,聚焦)

基于扩散的图像超分辨率&#xff08;SR&#xff09;方法主要受到数百甚至数千个采样步骤要求导致推理速度低的限制。现有的加速度采样技术不可避免地在一定程度上牺牲了性能&#xff0c;导致SR结果过于模糊。为了解决这个问题&#xff0c;我们提出了一种新颖而高效的SR扩散模型…

天池SQL训练营(四)-集合运算-表的加减法和join等

-天池龙珠计划SQL训练营 4.1表的加减法 4.1.1 什么是集合运算 集合在数学领域表示“各种各样的事物的总和”, 在数据库领域表示记录的集合. 具体来说,表、视图和查询的执行结果都是记录的集合, 其中的元素为表或者查询结果中的每一行。 在标准 SQL 中, 分别对检索结果使用 U…

AWS Ubuntu设置DNS解析(解决resolve.conf被覆盖问题)

众所周知&#xff1a; Ubuntu在域名解析时&#xff0c;最直接使用的是/etc/resolve.conf文件&#xff0c;它是/run/systemd/resolve/resolve.conf的软链接&#xff0c;而对于刚装完的ubuntu系统&#xff0c;该文件的内容如下 ubuntuip-172-31-36-184:/etc$ cat resolv.conf #…

02-Nacos和Eureka的区别与联系

Nacos和Eureka的区别 联系 Nacos和Eureka整体结构类似: 都支持服务注册, 服务拉取, 采用心跳方式对服务提供者做健康监测的功能 区别 Nacos支持服务端主动检测服务提供者状态: 临时实例采用心跳模式,非临时实例采用主动检测模式但对服务器压力比较大(不推荐) 心跳模式: 服务…

华为数通方向HCIP-DataCom H12-831题库(多选题:161-180)

第161题 以下关于IS-IS路由渗透的描述,正确的有哪些项? A、若要配置Level-2区域的路由向Level-1区域渗透,则需要在Level-1设备上配置命令import-routeisis level_-2 into level_-1 B、缺省情况下,Level-2区域无Level-1区域的路由信息,需要通过在Level-1-2设备上配置impor…

PPT插件-好用的插件-插入媒体-大珩助手

批量媒体 包含批量视频、批量音频、批量图片&#xff0c;可实现从光标所在的位置开始&#xff0c;每页插入一个视频、一个音频、一张图片&#xff0c;且图片和视频的尺寸与当前幻灯片尺寸一致 插入文本 包含黑字无底、白字红底、白字黛底、白字绿底、白字蓝底预设一键文本&am…

C++12.5

想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有一位讲解员&#xff0c;他会为每种动物表演做简单的介绍。 在这个场景中&#xff0c;我们可以将动物比作是不同的类&#xff0c;而每种动物表演则…

三相不平衡电压的正负序分析

1、什么是正负序&#xff1f; ABC 正序 ACB 负序 2、在abc坐标系下 接着利用矢量的旋转消去其它分量。。。 同理&#xff0c;得到其它的所有正负序的分量abc 3、在α/β坐标系下&#xff0c; 依次算出正负序的α/β来表示的abc 有一点需要特别注意&#xff0c;可以看到…

Java类对象的操作

1.Student.java package Message; public class Student {private String stuName; // 姓名private int money; // 存款余额private String studentID; // 学号private int age; // 年龄private String address; // 地址private String phoneNumber; // 电话号码private String…

同名称的文件如何批量指定到同名称文件夹中保存

在日常工作中相信大家都是会遇到文件或文件名修改名称、或文件批量归类保存等等&#xff0c;相对来文件或文件夹批量重命名会比较好操作&#xff0c;如果遇到按文件名称批量到指定同名称文件夹中保存呢&#xff1f;这可要什么来实现呢&#xff0c;到底能不能实现出来。接下来大…

Go1.21.0 程序启动过程

版本说明 Go 1.21.0操作系统&#xff1a;Windows11 Intel64 结论先行 开发关注版 在 Go 语言中&#xff0c;启动顺序通常如下&#xff1a; 导入包&#xff1a;首先&#xff0c;Go 编译器按照源文件中的 import 语句导入所有需要的包。初始化常量和变量&#xff1a;接着&am…

SpringBoot自定义参数校验注解

为什么要自定义校验注解? 当现有的注解NotEmptyPatternNotNullURl等不能满足业务需求的时候,我们需要手动自定义一个注解 操作步骤 新建一个anno的包 单击右键添加注解 编写state注解 创建validation文件夹 编写校验规则 然后给上面的State注解指定这个校验规则 使用注解…