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

在上一篇文章的基础上,我们将进一步扩展功能,实现在生成的二维码中嵌入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.mfbz.cn/a/343876.html

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

相关文章

图像处理------负片

什么是负片&#xff1f; 负片是经曝光和显影加工后得到的影像&#xff0c;其明暗与被摄体相反&#xff0c;其色彩则为被摄体的补色&#xff0c;它需经印放在照片上才还原为正像。我们平常所说的用来冲洗照片的底片就是负片。 """将彩色图像转换成负片 "&…

Java的异常 Exception

从继承关系可知:Throwable 是异常体系的根&#xff0c;它继承自Object 。Throwable 有两个体系: Error 和Exception. Error表示严重的错误&#xff0c;程序对此一般无能为力,例如: OutOfMemoryError :内存耗尽NoClassDefFoundError :无法加载某个ClassStackOverflowError :虚…

V∗: Guided Visual Search as a Core Mechanism in Multimodal LLMs

摘要 当我们环顾四周并执行复杂任务时&#xff0c;我们如何看待和选择性地处理我们所看到的是至关重要的。然而&#xff0c;这种视觉搜索机制的缺乏&#xff0c;在目前的多模态LLM&#xff08;MLLM&#xff09;阻碍了他们的能力&#xff0c;专注于重要的视觉细节&#xff0c;特…

c++:类和对象(2),对象的初始化和清理

目录 构造函数和析构函数 构造函数语法&#xff1a;类名&#xff08;&#xff09;{} 析构函数语法: ~类名 () {} 例子&#xff1a; 构造函数的分类及调用 两种分类的方式&#xff1a; 三种调用方法&#xff1a; 括号法​编辑 显示法 隐式转换法 拷贝构造函数调用时…

Python range函数

Python中的range()函数是一个强大的工具&#xff0c;用于生成一系列的整数。它在循环、迭代和序列生成等方面都有广泛的应用。本文将深入探讨range()函数的用法&#xff0c;提供详细的示例代码&#xff0c;并讨论其在Python编程中的实际应用。 什么是range()函数&#xff1f; …

springboot导出数据到excel模板,使用hutool导出数据到指定excel,java写入数据到excel模板

最近遇到一个需求&#xff0c;需要从数据库查询数据&#xff0c;写入到对应的excel导入模板中。再把导出的数据进行修改&#xff0c;上传。 我们项目用的是easyExcel&#xff0c;一顿百度搜索&#xff0c;不得其法。 主要是要把数据填充到指定单元格中&#xff0c;跟平时用到的…

计算机网络实验二:Packet Tracer的简单使用

目录 实验二&#xff1a;Packet Tracer的简单使用 2.1 实验目的 2.2 实验步骤 2.2.1 构建网络拓扑 2.2.2 配置各网络设备 2.2.3 网络功能验证测试 2.3 实验总结 实验二&#xff1a;Packet Tracer的简单使用 2.1 实验目的 ①练习packet tracer仿真软件的安装&#xff1…

mc我的世界服务器多少钱一个月?

我的世界服务器多少钱一个月&#xff1f;低至7元一个月&#xff0c;阿里云和腾讯云均可以选择mc服务器&#xff0c;阿里云2核2G3M轻量服务器87元一年、腾讯云轻量2核2G3M服务器88元一年&#xff0c;阿里云ECS云服务器2核2G3M带宽99元一年&#xff0c;腾讯云2核4G5M带宽轻量应用…

活动回顾丨云原生技术实践营上海站「云原生 AI 大数据」专场(附 PPT)

AI 势不可挡&#xff0c;“智算”赋能未来。2024 年 1 月 5 日&#xff0c;云原生技术实践营「云原生 AI &大数据」专场在上海落幕。活动聚焦容器、可观测、微服务产品技术领域&#xff0c;以云原生 AI 工程化落地为主要方向&#xff0c;希望帮助企业和开发者更快、更高效地…

菜鸡后端的前端学习记录

前言 记录一下看视频学习前端的的一些笔记&#xff0c;以前对Html、Js、CSS有一定的基础&#xff08;都认得&#xff0c;没用过&#xff09;&#xff0c;现在不想从头再来了&#xff0c;学学Vue框架&#xff0c;不定时更新&#xff0c;指不定什么时候就鸽了。。。。 Vue2 01…

初识汇编指令

1. ARM汇编指令 目的 认识汇编, 从而更好的进行C语言编程 RAM指令格式: 了解 4字节宽度 地址4字节对齐 方便寻址 1.1 指令码组成部分 : condition: 高4bit[31:28] 条件码 0-15 &#xff08;16个值 &#xff09; 条件码: 用于指令的 条件执行 , ARM指定绝大部分 都可…

Linux之快速入门(CentOS 7)

文章目录 一、Linux目录结构二、常用命令2.1 切换用户2.2查看ip地址2.3 cd2.4 目录查看2.5 查看文件内容2.6 创建目录及文件2.7 复制和移动2.82.93.0 一、Linux目录结构 目录作用/bin是 Binaries (二进制文件) 的缩写,这个目录存放着最经常使用的命令/dev是 Device(设备) 的缩写…

【GitHub项目推荐--不错的Rust开源项目】【转载】

01 Rust 即时模式 GUI 库 egui 是一个简单、快速且高度可移植的 Rust 即时模式 GUI 库&#xff0c;可以轻松地将其集成到你选择的游戏引擎中&#xff0c;旨在成为最易于使用的 Rust GUI 库&#xff0c;以及在 Rust 中制作 Web 应用程序的最简单方法。 项目地址&#xff1a;ht…

go 依赖注入设计与实现

在现代的 web 框架里面&#xff0c;基本都有实现了依赖注入的功能&#xff0c;可以让我们很方便地对应用的依赖进行管理&#xff0c;同时免去在各个地方 new 对象的麻烦。比如 Laravel 里面的 Application&#xff0c;又或者 Java 的 Spring 框架也自带依赖注入功能。 今天我们…

【ASOC全解析(一)】ASOC架构简介和欲解决的问题

【ASOC全解析&#xff08;一&#xff09;】ASOC架构简介和欲解决的问题 一、什么是ASOC以及ASOC解决的三个问题二、ASOC的组成与功能解决第一个问题解决第二个问题解决第三个问题 三、ASOC基本工作原理 /********************************************************************…

Parade Series - Android Studio

硬件支持 CPU i7 RAM 16Gb -------------- ------- Java 3Gb Android 33GbJava Enviroment C:\ ├─ Java │ ├─ jdk1.8.0_181 │ ├─ jre1.8.0_181 │ ├─ maven-3.8.5 │ └─ gradle-6.5 └─ Cache├─ gr…

基于中文垃圾短信数据集的经典文本分类算法实现

垃圾短信的泛滥给人们的日常生活带来了严重干扰&#xff0c;其中诈骗短信更是威胁到人们的信息与财产安全。因此&#xff0c;研究如何构建一种自动拦截过滤垃圾短信的机制有较强的实际应用价值。本文基于中文垃圾短信数据集&#xff0c;分别对比了朴素贝叶斯、逻辑回归、随机森…

哈希--73. 矩阵置零/medium 理解度A

73. 矩阵置零 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,…

Overleaf(LaTeX文档在线编写平台)使用学习记录

一、LaTeX简概[1] LaTeX&#xff0c;是一种基于TEX的排版系统&#xff0c;是一种可以处理排版和渲染的标记语言。由美国计算机科学家莱斯利兰伯特在20世纪80年代初期开发&#xff0c;利用这种格式系统的处理&#xff0c;即使用户没有排版和程序设计的知识也可以充分发挥由TEX所…

CACTER邮件安全网关独家安全解决方案——保障企业邮件系统安全

随着科技的不断发展&#xff0c;网络攻击技术也在不断演变&#xff0c;尤其是在电子邮件领域&#xff0c;各种高级变种威胁层出不穷&#xff0c;比如定制化的钓鱼邮件和带有高级恶意软件的邮件等。这些威胁邮件往往能够绕过传统的安全防护措施&#xff0c;包括反垃圾邮件、反钓…
最新文章