在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 {@Autowiredprivate 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.mzph.cn/news/643406.shtml

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

相关文章

HIS项目介绍、项目环境准备、版本控制介绍、Git基础、Git指针、Git分支、Git标签

案例1&#xff1a;项目环境准备 环境准备说明&#xff1a; 本阶段共使用虚拟机6台&#xff0c;操作系统使用RockyLinux8.6 环境准备要求&#xff1a; 最小化安装即可配置好主机名和IP地址搭建好yum源关闭防火墙和SELinux!!! 项目主机列表 主机名IP地址规格角色服务Progra…

上位机图像处理和嵌入式模块部署(windows opencv)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 opencv可以运行在多个平台上面&#xff0c;当然windows平台也不意外。目前来说&#xff0c;opencv使用已经非常方便了&#xff0c;如果不想自己编译…

红黑树浅浅学习

红黑树浅浅学习 红黑树概念红黑树平衡性调整 红黑树概念 二叉树&#xff1a;二叉树是每个节点最多有两个子树的树结构。二叉查找树&#xff1a;又称“二叉搜索树”&#xff0c;左孩子比父节点小&#xff0c;右孩子比父节点大&#xff0c;还有一个特性就是”中序遍历“可以让结…

element-ui 打包流程源码解析——babel 相关

目录 1&#xff0c;babel-cli2&#xff0c;babel-core3&#xff0c;.babelrc3.1&#xff0c;presets3.2&#xff0c;plugins其他相关 该文章是为了更好的理解&#xff1a;element-ui 打包流程源码解析&#xff08;上&#xff09; 第2.5节 npm run build:utils 打包命令 "…

初识SQL注入

目录 注入攻击 SQL注入 手工注入 Information_schema数据库 自动注入 介绍一下这款工具&#xff1a;sqlmap 半自动注入 前面给大家通过学习练习的方式将XSS攻击的几种形式和一些简单的靶场和例题的演示&#xff0c;从本篇开始我将和小伙伴们通过边复习、边练习的方式来进…

Android 访问存储卡的三种主要的目录

Android 访问存储卡&#xff08;即外部存储&#xff09;通常涉及以下三种主要的目录&#xff1a; 1. 外部存储公共目录 (Public External Storage) 这些目录对所有应用都是可见的&#xff0c;并且不需要任何特殊权限来读取媒体文件。但是从Android 10&#xff08;API 级别 29…

深入浅出hdfs-hadoop基本介绍

一、Hadoop基本介绍 hadoop最开始是起源于Apache Nutch项目&#xff0c;这个是由Doug Cutting开发的开源网络搜索引擎&#xff0c;这个项目刚开始的目标是为了更好的做搜索引擎&#xff0c;后来Google 发表了三篇未来持续影响大数据领域的三架马车论文&#xff1a; Google Fil…

猫用空气净化器哪些好?五款宠物空气净化推荐!

如今&#xff0c;养宠物的家庭越来越多了&#xff01;家里因此变得更加温馨&#xff0c;但同时也会带来一些问题&#xff0c;比如异味和空气中的毛发可能会对健康造成困扰。 为了避免家中弥漫着异味&#xff0c;特别是来自宠物便便的味道&#xff0c;一款能够处理家里异味的宠…

第17章 项目干系人管理

文章目录 项目干系人管理包括识别能够影响项目或会受项目影响的人员、团体或组织&#xff0c;分析干系人对项目的期望和影响&#xff0c;制定管理策略有效调动干系人参与项目决策和执行。 17.1管理基础 17.1.1管理的重要性 每个项目都有干系人&#xff0c;他们会受到项目积极或…

PHP+SOCKET 服务端多进程处理多客户端请求 demo

服务端 $socket socket_create(AF_INET,SOCK_STREAM,SOL_TCP); socket_bind($socket,0,95012) or die( server bind fail: . socket_strerror(socket_last_error())); socket_listen($socket,5);$child 0; //初始化子进程数 while(true){$client socket_accept($socket);$pi…

【大数据】YARN调度器及调度策略

YARN调度器 YARN负责作业资源调度&#xff0c;在集群中找到满足业务的资源&#xff0c;帮助作业启动任务&#xff0c;管理作业的生命周期。 ​ YARN技术架构 ​ 目前&#xff0c;Hadoop作业调度器主要有三种&#xff1a;先进先出调度器&#xff08;First In First Out&…

electron-updater使用整理

参考文章&#xff1a; 手撸 Electron 自动更新&#xff0c;再繁琐也要搞懂它 - 掘金 (juejin.cn)Electron 自动更新&#xff0c;绕过 latest.yml 使用自定义接口 - 掘金 (juejin.cn)electron-updater实现热更新完整流程 - 掘金 (juejin.cn) 一、 配置 1. 安装electron-updat…

【正点原子STM32】搭建开发环境(安装MDK和器件支持包、DAP仿真器和ST LINK仿真器、CH340串口驱动)

一、常用开发工具简介 MDKDAP 二、安装MDK 1、MDK简介2、如何获取MDK3、安装MDK和器件支持包 三、安装仿真器驱动 DAP仿真器免驱ST LINK仿真器驱动安装方法 ST LINK驱动及教程 四、安装CH340 USB虚拟串口驱动 1、安装CH340 USB虚拟串口驱动2、为什么要安装CH340 USB虚拟…

Google ASPIRE框架:赋予大型语言模型(LLMs)自我评估的新动力

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

大数据学习之Flink、比较不同框架的容错机制

第一章、Flink的容错机制 第二章、Flink核心组件和工作原理 第三章、Flink的恢复策略 第四章、Flink容错机制的注意事项 第五章、Flink的容错机制与其他框架的容错机制相比较 目录 第五章、Flink的容错机制与其他框架的容错机制相比较 Ⅰ、Flink的容错机制与其他框架的容…

springboot 整合 ElasticSearch 方法 (一)

下载 ES 相当于安装 MySQL, 可以在官网上下载 (链接在后面). 要注意安装的 ES 的版本要和项目中用的 Springboot 的版本对应. 比如我用的 Springboot 版本是 2.6, 所以ES要下载7.15 版本的. 官网链接: https://www.elastic.co/cn/downloads/elasticsearch 点右边这个查看更多…

腾讯云4核8G12M服务器我的世界mc够多少人?

mc我的世界服务器4核8g够多少人&#xff1f;80人&#xff0c;4核8G服务器最多支持80人同时在线。关于我的世界服务器的CPU和内存有用户测试过&#xff0c;阿腾云atengyun.com认为最多可以支持80人同时在线。如果运行的云服务器配置较低&#xff0c;启动游戏后可以在左下角看到配…

展厅设计更好的方法

一、与公司形象契合 在展厅规划时必定要留意公司的LOGO、主色调&#xff0c;以及企业文明。在展现时使用丰满的展厅规划传达出企业的理念。而在功用设置上&#xff0c;应当考虑内涵功用&#xff0c;从展厅作业人员的视点动身&#xff0c;为展厅作业人员提供杰出的环境&#xff…

【Java】---反射:Class、Filed、Constructor、Method

【Java】—反射 文章目录 【Java】---反射一、反射1.1 概念1.2 操作步骤 二、Class类2.1 概念2.2 方法2.2.1 getName()2.2.2 getSimpleName()2.2.3 getPackage()2.2.4 getSuperclass()2.2.5 getInterfaces() 三、Field类3.1 概念3.2 方法3.2.1 setAccessible(Boolean b)3.2.2 s…

关于图像分割项目的可视化脚本

1. 前言 之前实现了目标检测和图像分类任务的可视化脚本&#xff0c;本章将最后一个分割任务的可视化脚本实现 效果展示如下&#xff1a; 代码会在当前目录保存展示好的图片&#xff0c;从左到右依次为&#xff0c;原图、mask图、mask覆盖在原图的掩膜图 关于目标检测的可视化…