在Spring Boot中使用ZXing开源库生成带有Logo的二维码

news2024/12/30 3:03:32

在上一篇文章的基础上,我们将进一步扩展功能,实现在生成的二维码中嵌入Logo图片。这样的二维码更具个性化和识别度。让我们逐步完成这个功能。

第一步:引入Logo图片

首先,准备一张用作Logo的图片,并确保它的大小适中。将Logo图片放置在项目的资源文件夹中,例如src/main/resources

第二步:修改生成服务

QRCodeService中添加新的方法,用于在生成二维码时添加Logo:

@Service
public class QRCodeService {
    @Value("${logo.path}")
    private String logoPath;

    // 定义一个名为generateQRCode的公共方法,它接收三个参数:content(字符串类型,表示二维码的内容)、width(整数类型,表示二维码的宽度)和height(整数类型,表示二维码的高度)。
    public byte[] generateQRCode(String content, int width, int height) {
        try {
            // 创建一个名为hints的HashMap对象,用于存储二维码编码的提示信息。
            Map<EncodeHintType, Object> hints = new HashMap<>();
            // 设置错误纠正级别为L,表示较低的纠错能力。
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            // 设置边距为2,即二维码边缘与内容之间的距离为2个像素。
            hints.put(EncodeHintType.MARGIN, 2);
            // 设置字符集为UTF-8,表示二维码支持UTF-8编码的字符。
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

            // 创建一个QRCodeWriter对象,用于生成二维码。
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            // 使用QRCodeWriter对象将内容编码为二维码,并指定宽度、高度和提示信息。
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            // 将BitMatrix对象转换为BufferedImage对象,以便于后续处理。
            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
            // 创建一个ByteArrayOutputStream对象,用于将BufferedImage对象转换为字节数组。
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // 将BufferedImage对象写入到ByteArrayOutputStream对象中,并指定输出格式为png。
            ImageIO.write(bufferedImage, "png", byteArrayOutputStream);

            // 将ByteArrayOutputStream对象中的数据转换为字节数组,并返回该字节数组。
            return byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            // 如果在生成二维码过程中出现异常,则打印异常信息。
            e.printStackTrace();
            // 返回空字节数组。
            return null;
        }
    }

    /**
     * 生成带有Logo的二维码
     *
     * @param content 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return 带有Logo的二维码的字节数组
     */
    public byte[] generateQRCodeWithLogo(String content, int width, int height) {
        try {
            // 调用方法生成二维码的字节数组
            byte[] qrCodeBytes = generateQRCode(content, width, height);

            // 从字节数组中读取二维码图像
            BufferedImage qrCodeImage = ImageIO.read(new ByteArrayInputStream(qrCodeBytes));
            System.out.println("logoPath"+logoPath);
            // 从指定路径读取Logo图像
            BufferedImage logoImage = ImageIO.read(new File(logoPath));

            // 计算Logo的大小,使其适合二维码的大小
            int logoWidth = qrCodeImage.getWidth() / 5;
            int logoHeight = qrCodeImage.getHeight() / 5;

            // 计算Logo在二维码上的位置,使其居中显示
            int x = (qrCodeImage.getWidth() - logoWidth) / 2;
            int y = (qrCodeImage.getHeight() - logoHeight) / 2;

            // 在二维码上绘制Logo图像
            Graphics2D graphics = qrCodeImage.createGraphics();
            graphics.drawImage(logoImage, x, y, logoWidth, logoHeight, null);
            graphics.dispose();

            // 将带有Logo的二维码转换为PNG格式的字节数组
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(qrCodeImage, "png", byteArrayOutputStream);

            // 返回带有Logo的二维码的字节数组
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            // 打印异常堆栈信息
            e.printStackTrace();
            // 返回空字节数组(表示失败)
            return null;
        }
    }
}

在上述代码中,我们添加了generateQRCodeWithLogo方法,该方法先调用generateQRCode生成普通二维码,然后在其基础上添加Logo。Logo的位置在二维码中央,大小为二维码的五分之一。

第三步:更新Controller

在Controller中调用新添加的方法,生成带有Logo的二维码:

@RestController
public class QRCodeController {

    @Autowired
    private QRCodeService qrCodeService;

    // 使用@GetMapping注解,表示这是一个处理HTTP GET请求的方法。
    // value属性指定了该方法对应的URL路径为"/generateQRCode"。
    // produces属性指定了该方法返回的数据类型,即PNG格式的图片。
    @GetMapping(value = "/generateQRCode", produces = MediaType.IMAGE_PNG_VALUE)
    public byte[] generateQRCode(@RequestParam String content,
                                 @RequestParam(defaultValue = "200") int width,
                                 @RequestParam(defaultValue = "200") int height) {
        // 调用qrCodeService的generateQRCode方法来生成二维码。
        // 传入二维码的内容、宽度和高度作为参数。
        return qrCodeService.generateQRCode(content, width, height);
    }

    /**
     * 生成带有Logo的二维码的API接口
     *
     * @GetMapping 注解表示这是一个处理HTTP GET请求的方法,并映射到"/generateQRCodeWithLogo"路径。
     * @RequestParam 注解用于从请求中获取参数。
     * @RequestParam(defaultValue = "200") 表示如果请求中没有提供该参数,则使用默认值"200"。
     * @Produces 注解指定此方法将产生或接受的媒体类型为"image/png"。
     *
     * @param content 二维码的内容,将从请求中获取。
     * @param width 二维码的宽度,将从请求中获取,默认为200。
     * @param height 二维码的高度,将从请求中获取,默认为200。
     *
     * @return 返回生成的带有Logo的二维码的字节数组。
     */

    @GetMapping(value = "/generateQRCodeWithLogo", produces = MediaType.IMAGE_PNG_VALUE)
    public byte[] generateQRCodeWithLogo(@RequestParam String content,
                                         @RequestParam(defaultValue = "200") int width,
                                         @RequestParam(defaultValue = "200") int height) {
        return qrCodeService.generateQRCodeWithLogo(content, width, height);
    }
}

我们在Controller中添加了新的接口/generateQRCodeWithLogo,该接口调用generateQRCodeWithLogo方法生成带有Logo的二维码。

第四步:配置Logo路径

application.propertiesapplication.yml中添加Logo路径的配置:

logo.path=classpath:logo.png

第五步:测试

在这里插入图片描述

通过以上步骤,你已经成功地在Spring Boot项目中使用ZXing生成带有Logo的二维码。这样的二维码更具有品牌特色,也更易于用户识别。希望这篇博文对你有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

硬件基础:数字电路概述与基础门电路

什么是数字逻辑电路 数字电路是一种利用离散信号进行信息处理的电子电路系统。 它的核心特点是使用数字信号来执行算术运算和逻辑运算。数字电路的工作信号是离散的&#xff0c;通常只取两个值&#xff1a;高电平和低电平&#xff0c;分别代表数值“1”和“0”。 这种电路的基础…

解决element-ui中的el-select选择器无法显示选中内容的问题

问题描述&#xff1a; 排查方法&#xff1a; 检查数据控制台是否报错&#xff0c;无报错 检查change是否触发&#xff0c;会触发 最后开始百度&#xff0c;查看文档 官方文档有这么一段话&#xff0c;就是属性一定要挂载到data上&#xff0c;不然无法检测。 最后解决&#…

视频监控怎么管理更有效率?用这个技术就够了!

视频监控系统在现代社会中扮演着重要的角色&#xff0c;随着技术的不断发展&#xff0c;视频监控系统不仅提高了安全性&#xff0c;还为企业提供了更多的数据和智能分析功能。 客户案例 工业制造 常州某制造企业希望提高生产线的效率和安全性。通过部署泛地缘科技推出的视频监…

6-微信小程序导航跳转、下拉触底、生命周期

导航 声明式导航 <navigator> 导航组件 官网传送门 导航到tabBar页面 在使用<navigator>跳转到tabbar页面需指定url和open-type属性&#xff0c;open-type必须为switchTab 例&#xff1a;从home页跳转到message wxml <navigator url"/pages/message/me…

【DeepLearning-1】 注意力机制(Attention Mechanism)

1.1注意力机制的基本原理&#xff1a; 计算注意力权重&#xff1a; 注意力权重是通过计算输入数据中各个部分之间的相关性来得到的。这些权重表示在给定上下文下&#xff0c;数据的某个部分相对于其他部分的重要性。 加权求和&#xff1a; 使用这些注意力权重对输入数据进行加权…

Socket-IO模型:初步模型

1、基础的一个C版本的服务器代码 依照C语言服务器的基础流程进行更改&#xff0c;整个的TCP链接流程的实现&#xff1a;接上篇 Socket编程-IO模型-CSDN博客 先上代码结构图&#xff0c;因为是示例 1、首先&#xff0c;这个示例的基本流程就是使用Socket&#xff0c;创建sockfd…

【C语言】(3)字符

字符串 1. 字符串简介 在C语言中&#xff0c;字符串是由字符数组构成的序列&#xff0c;以空字符&#xff08;\0&#xff09;结尾。这个空字符不可见&#xff0c;用于标记字符串的结束。C语言中没有专门的字符串类型&#xff0c;通常使用字符数组表示字符串。 2. 声明和初始…

Redis 高可用之主从复制

1、简介 在 Redis 中&#xff0c;主从复制就是多个节点进行数据同步&#xff0c;在这些节点中&#xff0c;有 Master 和 slave 两个角色&#xff0c;Master 以写为主&#xff0c;slave 以读为主&#xff0c;当 Master 数据变化的时候&#xff0c;会自动将新的数据同步到其他的 …

让代码在键盘上跳“华尔兹”的10大原则

大家好&#xff0c;我是小❤&#xff0c;一个漂泊江湖多年的 985 非科班程序员&#xff0c;曾混迹于国企、互联网大厂和创业公司的后台开发攻城狮。 引言 编程界都知道&#xff0c;代码是一种艺术 —— 它是对技术职责和美学眼光的完美融合。 正如一名工匠在雕琢他的作品&am…

白酒:制曲工艺的特点与核心技术

白酒&#xff0c;其制曲工艺是品质的关键所在。制曲是酿酒过程中重要的环节&#xff0c;对于酒的口感和品质有着至关重要的影响。在云仓酒庄豪迈白酒的制曲工艺中&#xff0c;有几个显著的特点和核心技术。 制曲原料丰富多样&#xff0c;除了常见的麦类&#xff0c;还可采用了…

菜鸟导入导出assetbundle

因为菜鸟不会用unity c#什么的&#xff0c;所以最后参考贴吧的方法用的是UABE(Unity Assets Bundle Extractor)和UABEA(Unity Assets Bundle Extractor Avalonia) 可以去github上下载 对于txt、xml什么的可以直接改&#xff0c;但是byte文件里还是会有一些类似乱码的东西&…

使用 Swift 代码优化项目编译速度

引言 软件的性能是评价一个软件质量的重要指标&#xff0c;尤其在今天这个时代&#xff0c;性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件&#xff0c;如网银系统、在线购物商城等&#xff0c;更是必须保证其高效稳定的性能。在这种背景下&#xff0c;优化…

AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(十)

又是认真学习的一天。 1.Git 初识 2.掌握 Git 仓库 3.Git 的三个区域 git ls-files 查看当前暂存区有哪些文件 4.Git 文件状态 5.Git 暂存区使用 使用git restore命令恢复修改过的index.css 使用git rm --catched命令从暂存区移除index.css文件 再用git add .放回9&#xff08;…

使用 SpringBoot 框架手撸一个本地缓存工具!

在实现本地缓存的时候&#xff0c;我们经常使用线程安全的ConcurrentHashMap来暂存数据&#xff0c;然后加上SpringBoot自带的Scheduled定时刷新缓存。虽然这样可以实现本地缓存&#xff0c;但既不优雅也不安全。 那看一下我的思路&#xff0c;首先看一张图! 1.每个处理器都有…

喷墨打印机市场分析:预计2029年将达到548亿美元

喷墨打印机是将彩色液体油墨经喷嘴变成细小微粒喷到印纸上,有的喷墨打印机有三个或四个打印喷头&#xff0c;以便打印黄、品红青黑四色;有的是共用一个喷头&#xff0c;分四色喷印。 喷墨打印机是在针式打印机之后发展起来的&#xff0c;采用非打击的工作方式。比较突出的优点有…

kubernetes Pod 异常排查步骤

kubernetes Pod 异常排查步骤 详细排查图查看容器状态查看容器列表容器未启动成功排查容器启动成功排查pod状态对应原因 详细排查图 查看容器状态 查看容器列表 查看容器列表,最好在后面跟上命名空间,不跟上查询出来是默认的 kubectl get pods -n kubesphere-system单独查看某…

eNSP学习——理解ARP及Proxy ARP

目录 名词解释 实验内容 实验目的 实验步骤 实验拓扑 配置过程 基础配置 配置静态ARP 名词解释 ARP (Address Resolution Protocol)是用来将IP地址解析为MAC地址的协议。ARP表项可以分为动态和静态两种类型。   动态ARP是利用ARP广播报文&#xff0c;动态执行并自动进…

sprignboot电商书城源码

运行环境: jdk1.8,maven,mysql 项目技术: 后台主要是springbootmybatisshirojsp&#xff0c;前端界面主要使用bootstrap框架搭建&#xff0c;并使用了ueditor富文本编辑器、highcharts图表库。 有需要的可以联系我。 功能介绍&#xff1a; 该系统分为前台展示和后台管理两…

芯课堂 | 通过ISP升级芯片固件方法及框架

一、升级原理 芯片在应用前&#xff0c;是一颗裸片&#xff0c;内部没有任何驱动或应用程序。芯片在贴上PCB板子后&#xff0c;会实现各种功能&#xff0c;这是时候会开发对应的驱动或者应用程序&#xff0c;在芯片上面运行的程序&#xff0c;一般称之为固件&#xff08;Firmw…

低代码,让软件开发不再复杂

低代码一词&#xff0c;有人认为它是第四代编程语言&#xff0c;有人认为它是开发模式的颠覆&#xff0c;也有人认为它是企业管理模式的变革……有很多声音&#xff0c;社区讨论很热烈。 即使这样&#xff0c;至今也有不少人还不知道这项技术&#xff0c;今天笼统的介绍一下低代…