Java实现生成中间带图标的二维码

Java实现生成中间带图标的二维码

生成Base64格式的二维码,返回html渲染

package your.package;import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;public class QRCodeWithLogo {public static void main(String[] args) throws Exception {String webUrl = "https://www.alibaba.com"; // 目标网址String logoPath = "alipay_logo.png"; // Logo图片文件路径int qrCodeSize = 200; // 二维码尺寸设置为300x300像素int logoSize = 50; // 定义Logo的宽度,留白区域大小// 调用函数生成带留白无logo的二维码图像BufferedImage qrCodeImage = generateQRCodeImage(webUrl, qrCodeSize, qrCodeSize, logoSize);// 调用函数在二维码中心加入支付宝logoBufferedImage qrCodeWithLogo = addLogoToQRCode(qrCodeImage, logoPath);// 调用函数将带有logo的二维码图像转换为Base64字符串String base64Encoded = convertImageToBase64(qrCodeWithLogo);System.out.println(base64Encoded); // 输出二维码的Base64编码字符串}/*** 生成带有中部空白区(为Logo预留空间)的二维码图像。* @param data 要编码到二维码中的数据字符串* @param width 生成的二维码图像宽度* @param height 生成的二维码图像高度* @param logoSize 预留给logo的空白区域的宽度与高度(假设空白区域为正方形)* @return 中央带有空白区域的二维码图像* @throws Exception 如果生成二维码时遇到任何错误,则抛出异常*/private static BufferedImage generateQRCodeImage(String data, int width, int height, int logoSize) throws Exception {// 配置二维码生成参数HashMap<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定二维码的编码设置为UTF-8hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置二维码的纠错级别为高(H)hints.put(EncodeHintType.MARGIN, 0); // 设置二维码边缘 空背空白(边框大小)为0// 根据数据与配置信息生成二维码的比特矩阵BitMatrix bitMatrix = new MultiFormatWriter().encode(data, BarcodeFormat.QR_CODE, width, height, hints);// 将二维码比特矩阵转换为BufferedImage图像,用于最终输出BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);// 计算中部logo空白区域的坐标位置// 这确保了空间位于二维码的正中心int deltaHeight = image.getHeight() - logoSize;int deltaWidth = image.getWidth() - logoSize;int coordX = deltaWidth / 2;int coordY = deltaHeight / 2;// 采用图形对象在图像上绘图Graphics2D g2 = image.createGraphics();// 设置compositing 规则定为SRC,通过AlphaComposite指定透明度效果g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));// 设置Logo区域的填充颜色为白色g2.setPaint(Color.WHITE);// 绘制一个填充过的矩形以形成预留给logo的空白区域g2.fillRect(coordX, coordY, logoSize, logoSize);g2.dispose(); // 结束图形编辑并释放系统资源return image; // 返回生成的二维码BufferedImage对象}/*** 将一个给定的logo图片添加到二维码中心** @param qrCodeImage 二维码的BufferedImage对象* @param logoPath logo图片的路径* @return 合成后的带有logo的二维码图片* @throws IOException 如果读取logo文件失败*/private static BufferedImage addLogoToQRCode(BufferedImage qrCodeImage, String logoPath) throws IOException {// 从文件中读取logo图片BufferedImage logoImage = ImageIO.read(new File(logoPath));// 确定logo的最终权重宽度和高度 - 通常将logo缩小到原来尺寸的1/5int logoWidth = logoImage.getWidth() / 5;int logoHeight = logoImage.getHeight() / 5;// 创建一个新的缓冲区图像,其中包含alpha值(透明度)用来画带边界的logoBufferedImage logoWithBorder = new BufferedImage(logoWidth, logoHeight, BufferedImage.TYPE_INT_ARGB);// 使用Graphics2D绘制带边界的logoGraphics2D gBorder = logoWithBorder.createGraphics();// 设置合成规则,表示后续绘图操作将直接替换背景像素gBorder.setComposite(AlphaComposite.Src);// 设置抗锯齿属性来平滑边缘gBorder.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 绘制一个填满整个logoWithBorder尺寸的白色矩形,形成logo的边界gBorder.setColor(Color.WHITE);gBorder.fillRect(0, 0, logoWidth, logoHeight);// 将logo图片缩放并绘制到logoWithBorder上gBorder.drawImage(logoImage.getScaledInstance(logoWidth, logoHeight, Image.SCALE_SMOOTH), 0, 0, null);// 不再进行绘制操作,释放此图形的上下文以及它使用的任何系统资源gBorder.dispose();// 计算二维码和logo的差距,用于将logo置于二维码的中心位置int deltaHeight = qrCodeImage.getHeight() - logoWithBorder.getHeight();int deltaWidth = qrCodeImage.getWidth() - logoWithBorder.getWidth();// 创建一个新的缓冲区图像以容纳原始的二维码和放置其中的logoBufferedImage combined = new BufferedImage(qrCodeImage.getHeight(), qrCodeImage.getWidth(), BufferedImage.TYPE_INT_ARGB);Graphics2D g = (Graphics2D) combined.getGraphics();// 将二维码绘制在新图片的最底层g.drawImage(qrCodeImage, 0, 0, null);// 设置合成效果来绘制logo,覆盖在之前绘制的内容之上g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));// 在合适的位置绘制带有白边背景框的logo(确保居中)g.drawImage(logoWithBorder, Math.round(deltaWidth / 2), Math.round(deltaHeight / 2), null);// 完成绘制,释放图形上下文使用的资源g.dispose();// 返回合成后带有logo的二维码图像return combined;}/*** 将图像转换成Base64编码的字符串* @param image* @return* @throws Exception*/private static String convertImageToBase64(BufferedImage image) throws Exception {ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 创建ByteArrayOutputStream对象ImageIO.write(image, "png", outputStream); // 把BufferedImage写入流中byte[] imageBytes = outputStream.toByteArray(); // 转换成对应的byte数组return Base64.getEncoder().encodeToString(imageBytes); // 进行Base64编码,并返回字符串}
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<img src="data:image/png;base64,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">
</body>
</html>

效果图

在这里插入图片描述

总结

上述代码是一个Java函数,主要目的是将logo图片加到二维码图片的中央位置上,完成之后返回这个合成后的图像,你也改造渲染成图片下载出来。

制作这样的二维码可以增加品牌辨识度或者美观性,在实际操作时,需要满足两个条件:

  1. logo不能过大,以免遮挡二维码导致难以扫描识别
  2. logo最好有一个边界,那样可以让logo与背景二维码区分开,这同样也是为了不影响二维码的可读性。

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

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

相关文章

DSPE-PEG-TPP 磷脂聚乙二醇-磷酸三苯酯 靶向线粒体纳米颗粒药物递送系统

DSPE-PEG-TPP 磷脂聚乙二醇-磷酸三苯酯 靶向线粒体纳米颗粒药物递送系统 【中文名称】磷脂-聚乙二醇-磷酸三苯酯 【英文名称】DSPE-PEG-TPP 【结 构】 【品 牌】碳水科技&#xff08;Tanshtech&#xff09; 【纯 度】95%以上 【保 存】-20℃ 【规 格】50mg,…

数字工厂系统的开发

数字工厂系统&#xff08;Digital Factory System&#xff0c;DFS&#xff09;是基于数字孪生技术&#xff08;Digital Twin Technology&#xff09;和信息物理融合系统&#xff08;Cyber-Physical System&#xff0c;CPS&#xff09;构建的&#xff0c;用于仿真、分析和优化制…

密码学 | 承诺:基本概念

目录 正文 1 承诺的交互 2 承诺的属性 3 硬币抛掷问题 3.1 朴素版方案 3.2 承诺版方案 &#x1f951;源自&#xff1a;https://en.wikipedia.org/wiki/Commitment_scheme &#x1f951;写在前面&#xff1a;英文的承诺是 commitment scheme&#xff0c;否则很难进行…

网络爬虫入门

爬虫&#xff08;也被称为网络爬虫或网络蜘蛛&#xff09;是一种自动化程序&#xff0c;它可以在互联网上自动抓取数据。爬虫的基本工作原理通常包括以下几个步骤&#xff1a;发送请求&#xff1a;爬虫向目标网站发送HTTP请求&#xff0c;请求网页内容。接收响应&#xff1a;爬…

根据 Figma 设计稿自动生成 Python GUI | 开源日报 No.221

ParthJadhav/Tkinter-Designer Stars: 8.0k License: BSD-3-Clause Tkinter-Designer 是一个用于快速创建 Python GUI 的工具&#xff0c;通过使用 Figma 设计软件&#xff0c;可以轻松地生成美观的 Tkinter GUI。 主要功能和优势包括&#xff1a; 拖放界面设计比手写代码更快…

百亿补贴低价的治理思路

各大电商平台都有陆续在推出百亿补贴通道&#xff0c;这对消费者来说&#xff0c;会更便捷&#xff0c;因为平台百亿补贴价格较低&#xff0c;不需要消费者再进行多链接、多平台的比价工作&#xff0c;直接下单即可&#xff0c;由于百亿补贴链接的上架主导权在平台&#xff0c;…

​面试经典150题——从前序与中序遍历序列构造二叉树

​ 1. 题目描述 2. 题目分析与解析 二叉树的前序、中序和后序遍历 二叉树的前序、中序和后序遍历是树的三种基本遍历方式&#xff0c;它们是通过不同的顺序来访问树中的节点的。 前序遍历&#xff08;Pre-order traversal&#xff09;&#xff1a; 访问根节点 前序遍历左子树…

详细介绍医用PSA变压吸附制氧机设备的工艺特点

随着技术的不断进步&#xff0c;医用氧气作为一种重要的治疗资源&#xff0c;其供应方式也在不断地改进和升级。其中&#xff0c;医用PSA(Pressure Swing Adsorption&#xff0c;变压吸附)变压吸附制氧机设备因其高效、安全、稳定的特点&#xff0c;受到了广大机构的青睐。那么…

Java高阶私房菜:快速学会异步编程CompletableFuture

为了使主程代码不受阻塞之苦&#xff0c;一般使用异步编程&#xff0c;而异步编程架构在JDK1.5便已有了雏形&#xff0c;主要通过Future和Callable实现&#xff0c;但其操作方法十分繁琐&#xff0c;想要异步获取结果,通常要以轮询的方式去获取结果&#xff0c;具体如下&#x…

传统零售行业如何做数字化转型?

传统零售行业的数字化转型是一个系统性的过程&#xff0c;涉及到企业的多个方面。以下是一些关键步骤和策略&#xff0c;帮助传统零售企业实现数字化转型&#xff1a; 1、明确转型目标和战略 首先&#xff0c;企业需要明确数字化转型的目标和战略。包括确定企业的核心竞争力、…

照片光晕光学特效模拟调色Boris FX Optics 2024 mac下载安装教程

Boris FX Optics 2024 Mac版是一款照片光晕光学特效模拟调色软件&#xff0c;旨在模拟光学相机滤镜&#xff0c;专用镜头&#xff0c;胶卷和颗粒&#xff0c;镜头光晕&#xff0c;光学实验室处理&#xff0c;色彩校正以及自然光和摄影效果。用户可以通过应用光学并从160个滤镜和…

HAL STM32 I2C方式读取MT6701磁编码器获取角度例程

HAL STM32 I2C方式读取MT6701磁编码器获取角度例程 &#x1f4cd;相关篇《Arduino通过I2C驱动MT6701磁编码器并读取角度数据》&#x1f388;《STM32 软件I2C方式读取MT6701磁编码器获取角度例程》&#x1f4cc;MT6701当前最新文档资料&#xff1a;https://www.magntek.com.cn/u…

甘特图:项目管理者的必备神器,如何提高工作效率?

甘特图是什么&#xff1f;项目管理者大多都熟悉甘特图&#xff0c;它是一种直观展示项目计划执行过程的工具。通过条形图来显示项目、任务的时间安排&#xff0c;以及实际进度与计划进度的对比情况。 在我个人的项目管理实践中&#xff0c;甘特图确实帮助我提高了工作效率&am…

威纶通触摸屏与S7-1200进行标签通信(符号寻址)的具体方法示例

威纶通与S7-1200进行标签通信(符号寻址)的具体方法示例 前面和大家分享了威纶通与S7-1200通过绝对地址进行以太网通信的具体方法,具体内容可参考以下链接中的内容: 威纶通触摸屏与S7-1200以太网通信的具体方法和步骤(非常详细) 如下图所示,打开博途软件,新建一个项目,…

中国老铁路增开对国际旅客列车开行

4月13日&#xff0c;中老铁路国际旅客列车开行一周年之际&#xff0c;中老两国铁路部门在中国西双版纳至老挝琅勃拉邦两大著名旅游城市间增开1对国际旅客列车&#xff0c;旅客乘火车可实现两地间当日往返。标题&#xff1a;古道新程——中国老铁路增开国际旅客列车 在这个日新月…

图书管理系统概述

自友图书馆管理系统解决方案适用于中小学、大中专院校以及企事业单位中小型图书馆的自动化管理需求&#xff0c;其功能覆盖了图书馆自动化集成管理业务流程所包括的所有环节。《图书馆管理系统》首先应该按照我国图书馆行业通用CNMARC格式及《中图法第四版》行业标准开发而成,支…

linux运行ant 报错 Unable to locate tools.jar【已解决】

linux安装 ant 运行时报错 Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.402.b06-1.el7_9.x86_64/lib/tools.jar 原因 已安装的jdk只有运行环境&#xff0c;没有tool.jar&#xff0c;而ant运行需要java开发环境&#xff0c;因…

第47篇:简易处理器<一>

Q&#xff1a;本期我们开始介绍一种数字系统----简易处理器&#xff0c;可以执行由指令指定的各种操作。 A&#xff1a;简易处理器包含多个9位寄存器、一个数据选择器、一个加/减法器单元和一个控制单元(有限状态机)。 数据选择器&#xff1a;可以将输入数据加载到各种寄存器&…

计算机网络-IS-IS基础概念二

前面已经学习了IS-IS的定义、组成、NET地址标识以及路由器级别分类等&#xff0c;今天继续学习IS-IS基础概念知识。 参考链接&#xff1a;IS-IS路由协议基础概念 一、IS-IS支持的网络类型 IS-IS会自动根据接口的数据链路层封装决定该接口的缺省网络类型&#xff0c; IS-IS支持两…

Biome 1.7 发布,支持从 ESLint 和 Prettier 迁移

近日&#xff0c;Biome v1.7 正式发布&#xff01;这个新版本提供了从 ESLint 和 Prettier 迁移的简单路径。它还引入了格式化程序和 linter 的实验性机器可读报告、新的 linter 规则和许多修复。 使用以下命令更新 Biome&#xff1a; npm install --save-dev --save-exact b…