springboot生成二维码和条形码

目录

    • springboot生成二维码和条形码
        • 引入依赖
        • 生成二维码,在controller层
        • 生成条形码controller

springboot生成二维码和条形码

引入依赖
<dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version>
</dependency><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.4.1</version>
</dependency>
生成二维码,在controller层
/*** 二维码控制器** @author onejson*/
@Slf4j
@OperateLog
@RestController
@RequestMapping(path = "/qrcode")
public class QrCodeController {// http://localhost:8080/qrcode/create?content=www.baidu.com@GetMapping(path = "/createQrCode")public void createQrCode(HttpServletResponse response, @RequestParam("content") String content) {try {// 创建二维码BufferedImage bufferedImage = QrCodeUtil.createImage(content, null, false);// 通过流的方式返回给前端responseImage(response, bufferedImage);} catch (Exception e) {e.printStackTrace();}}/*** 设置 可通过 postman 或者浏览器直接浏览** @param response      response* @param bufferedImage bufferedImage* @throws Exception e*/public void responseImage(HttpServletResponse response, BufferedImage bufferedImage) throws Exception {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ImageOutputStream imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream);ImageIO.write(bufferedImage, "jpeg", imageOutput);InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());OutputStream outputStream = response.getOutputStream();response.setContentType("image/jpeg");response.setCharacterEncoding("UTF-8");IOUtils.copy(inputStream, outputStream);outputStream.flush();}
}

对应的二维码工具类

@Component
public class QrCodeUtil {private static final String CHARSET = "UTF-8";private static final String FORMAT_NAME = "JPG";/*** 二维码尺寸*/private static final int QRCODE_SIZE = 300;/*** LOGO宽度*/private static final int WIDTH = 60;/*** LOGO高度*/private static final int HEIGHT = 60;/*** 创建二维码图片** @param content    内容* @param logoPath   logo* @param isCompress 是否压缩Logo* @return 返回二维码图片* @throws WriterException e* @throws IOException     BufferedImage*/public static BufferedImage createImage(String content, String logoPath, boolean isCompress) throws WriterException, IOException {Hashtable<EncodeHintType, Object> hints = new Hashtable<>();// 设置二维码的错误纠正级别 高hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 设置字符集hints.put(EncodeHintType.CHARACTER_SET, CHARSET);// 设置边距hints.put(EncodeHintType.MARGIN, 1);// 生成二维码BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}if (logoPath == null || "".equals(logoPath)) {return image;}// 在二维码中增加 logoQrCodeUtil.insertImage(image, logoPath, isCompress);return image;}/*** 添加Logo** @param source     二维码图片* @param logoPath   Logo* @param isCompress 是否压缩Logo* @throws IOException void*/private static void insertImage(BufferedImage source, String logoPath, boolean isCompress) throws IOException {File file = new File(logoPath);if (!file.exists()) {return;}Image src = ImageIO.read(new File(logoPath));int width = src.getWidth(null);int height = src.getHeight(null);// 压缩LOGOif (isCompress) {if (width > WIDTH) {width = WIDTH;}if (height > HEIGHT) {height = HEIGHT;}Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = tag.getGraphics();// 绘制缩小后的图g.drawImage(image, 0, 0, null);g.dispose();src = image;}// 插入LOGOGraphics2D graph = source.createGraphics();int x = (QRCODE_SIZE - width) / 2;int y = (QRCODE_SIZE - height) / 2;graph.drawImage(src, x, y, width, height, null);Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);graph.setStroke(new BasicStroke(3f));graph.draw(shape);graph.dispose();}/*** 生成带Logo的二维码** @param content    二维码内容* @param logoPath   Logo* @param destPath   二维码输出路径* @param isCompress 是否压缩Logo* @throws Exception void*/public static void create(String content, String logoPath, String destPath, boolean isCompress) throws Exception {BufferedImage image = QrCodeUtil.createImage(content, logoPath, isCompress);mkdirs(destPath);ImageIO.write(image, FORMAT_NAME, new File(destPath));}/*** 生成不带Logo的二维码** @param content  二维码内容* @param destPath 二维码输出路径*/public static void create(String content, String destPath) throws Exception {QrCodeUtil.create(content, null, destPath, false);}/*** 生成带Logo的二维码,并输出到指定的输出流** @param content    二维码内容* @param logoPath   Logo* @param output     输出流* @param isCompress 是否压缩Logo*/public static void create(String content, String logoPath, OutputStream output, boolean isCompress) throws Exception {BufferedImage image = QrCodeUtil.createImage(content, logoPath, isCompress);ImageIO.write(image, FORMAT_NAME, output);}/*** 生成不带Logo的二维码,并输出到指定的输出流** @param content 二维码内容* @param output  输出流* @throws Exception void*/public static void create(String content, OutputStream output) throws Exception {QrCodeUtil.create(content, null, output, false);}/*** 二维码解析** @param file 二维码* @return 返回解析得到的二维码内容* @throws Exception String*/public static String parse(File file) throws Exception {BufferedImage image;image = ImageIO.read(file);if (image == null) {return null;}BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));Result result;Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();hints.put(DecodeHintType.CHARACTER_SET, CHARSET);result = new MultiFormatReader().decode(bitmap, hints);return result.getText();}/*** 二维码解析** @param path 二维码存储位置* @return 返回解析得到的二维码内容* @throws Exception String*/public static String parse(String path) throws Exception {return QrCodeUtil.parse(new File(path));}/*** 判断路径是否存在,如果不存在则创建** @param dir 目录*/public static void mkdirs(String dir) {if (dir != null && !"".equals(dir)) {File file = new File(dir);if (!file.isDirectory()) {file.mkdirs();}}}
}

访问预览

image-20241105100502549

生成条形码controller
/*** 条形码控制器** @author onejson*/
@Slf4j
@OperateLog
@RestController
@RequestMapping(path = "/barcode")
public class BarCodeController {// http://localhost:8080/barcode/createCode?content=987654132&barCodeWord=123456789@GetMapping(path = "/createCode")public void createQrCode(HttpServletResponse response, @RequestParam("content") String content, @RequestParam("content") String barCodeWord) {try {// 创建二维码ByteArrayOutputStream byteArrayOutputStream = BarCodeUtil.barcodeGenerator(content, barCodeWord);// 通过流的方式返回给前端InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());OutputStream outputStream = response.getOutputStream();response.setContentType("image/jpeg");response.setCharacterEncoding("UTF-8");IOUtils.copy(inputStream, outputStream);outputStream.flush();} catch (Exception e) {e.printStackTrace();}}}

对应的工具类 BarCodeUtil

@Component
public class BarCodeUtil {/*** 条形码宽度*/private static final int WIDTH = 200;/*** 条形码高度*/private static final int HEIGHT = 50;/*** 生成条形码,并加文字,以流的方式返回** @param content     内容* @param barCodeWord 二维码的文字* @return ByteArrayOutputStream*/public static ByteArrayOutputStream barcodeGenerator(String content, String barCodeWord) {// 设置条形码参数HashMap<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 设置纠错级别为L(低)hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符编码为UTF-8try {// 生成条形码的矩阵BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.CODE_128, WIDTH, HEIGHT, hints);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(matrix);//底部加单号BufferedImage image = insertWords(bufferedImage, barCodeWord);if (Objects.isNull(image)) {throw new RuntimeException("条形码加文字失败");}ImageIO.write(image, "png", outputStream);return outputStream;} catch (WriterException | IOException e) {throw new RuntimeException("条形码生成失败", e);}}private static BufferedImage insertWords(BufferedImage image, String words) {// 新的图片,把带logo的二维码下面加上文字if (StringUtils.hasLength(words)) {BufferedImage outImage = new BufferedImage(WIDTH, HEIGHT + 20, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = outImage.createGraphics();// 抗锯齿setGraphics2D(g2d);// 设置白色setColorWhite(g2d);// 画条形码到新的面板g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);// 画文字到新的面板Color color = new Color(0, 0, 0);g2d.setColor(color);// 字体、字型、字号g2d.setFont(new Font("微软雅黑", Font.PLAIN, 16));//文字长度int strWidth = g2d.getFontMetrics().stringWidth(words);//总长度减去文字长度的一半  (居中显示)int wordStartX = (WIDTH - strWidth) / 2;//height + (outImage.getHeight() - height) / 2 + 12int wordStartY = HEIGHT + 20;// time 文字长度// 画文字g2d.drawString(words, wordStartX, wordStartY);g2d.dispose();outImage.flush();return outImage;}return null;}/*** 设置 Graphics2D 属性  (抗锯齿)** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setGraphics2D(Graphics2D g2d) {// 消除画图锯齿g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 消除文字锯齿g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);g2d.setStroke(s);}private static void setColorWhite(Graphics2D g2d) {g2d.setColor(Color.WHITE);//填充整个屏幕g2d.fillRect(0, 0, WIDTH, HEIGHT + 20);//设置笔刷g2d.setColor(Color.BLACK);}
}

apifox预览效果

image-20241105100934654

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

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

相关文章

RTSP播放器EasyPlayer.js无插件直播流媒体音视频播放器使用http与https的区别

在当今数字化时代&#xff0c;视频播放体验的重要性日益凸显&#xff0c;而EasyPlayer.js无插件H5播放器作为一款现代Web环境下的播放器&#xff0c;其对HTTP和HTTPS的支持成为了许多用户关注的焦点。本文将探讨EasyPlayer.js播放器在使用HTTP与HTTPS时的区别。 1、从安全性角度…

组态软件基础知识

一、组态软件基础知识 1、概述 &#xff08;1&#xff09;、组态软件概念与产生背景 “组态”的概念是伴随着集散型控制系统&#xff08;Distributed Control System简称DCS&#xff09;的出现才开始被广大的生产过程自动化技术人员所熟知的。在工业控制技术的不断发…

国标GB28181公网直播EasyGBS国标GB28181视频平台与海康GB28181对接需要做哪些测试?

在当今的视频监控系统中&#xff0c;国标GB28181协议已成为视频监控设备互联互通的标准。特别是在公网直播的应用场景中&#xff0c;国标GB28181公网直播EasyGBS国标GB28181视频平台与海康威视设备的对接显得尤为重要。为了确保对接的顺利进行&#xff0c;需要进行一系列详尽的…

SpringBoot使用TraceId日志链路追踪

项目场景&#xff1a; 有时候一个业务调用链场景&#xff0c;很长&#xff0c;调了各种各样的方法&#xff0c;看日志的时候&#xff0c;各个接口的日志穿插&#xff0c;确实让人头大。为了解决这个痛点&#xff0c;就使用了TraceId&#xff0c;根据TraceId关键字进入服务器查询…

【QML】QML图表(ChartView)改变坐标轴(ValueAxis)标题(titleText)的文字颜色

1. 需求 改变titleText的颜色&#xff0c;将下图mV的颜色改为红色 2.代码 关键代码&#xff1a;titleText: "<font colorred>mV</font>" //坐标轴 mv ValueAxis{id: _mAxisMvmin: 0max: 20tickCount: 6labelsFont.pixelSize: 15labelFormat: %.1ft…

mysql诡异查询

运营同事让查一个数量&#xff0c;结果这两种情况查的居然不一致。 带时分秒查询的是另一个数&#xff0c;没有时分秒是上面的&#xff0c;少了100多条数据&#xff0c;为什么&#xff0c;有路过的大神可以指点一二。

丹摩征文活动|快速上手 CogVideoX-2b:智谱清影 6 秒视频生成部署教程

文章目录 一、生成视频效果 二、CogVideoX 技术新起点三、CogVideoX 上手部署3.1 创建丹摩实例3.2 配置环境和依赖3.3 模型与配置文件3.4 运行3.5 问题与处理方法 四、CogVideoX-2b 用创新点燃未来 一、生成视频效果 A street artist, clad in a worn-out denim jacket and a c…

仓库管理系统的实施流程超全解析!

现在我们都能很清楚地知道&#xff0c;在企业管理中仓库管理系统&#xff08;WMS&#xff09;扮演着非常重要的角色。而且随着电子商务的迅猛发展和供应链管理的复杂化&#xff0c;企业对仓库管理的要求越来越高。那么&#xff0c;如何有效地实施一个仓库管理系统&#xff0c;成…

【K8S问题系列 | 10】在K8S集群怎么查看各个pod占用的资源大小?【已解决】

要查看 Kubernetes 集群中各个 Pod 占用的资源大小&#xff08;包括 CPU 和内存&#xff09;&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用 kubectl top 命令 kubectl top 命令可以快速查看当前 Pod 的 CPU 和内存使用情况。需要确保已安装并配置了 Metrics Server。…

YOLO即插即用模块---MEGANet

MEGANet: Multi-Scale Edge-Guided Attention Network for Weak Boundary Polyp Segmentation 论文地址&#xff1a; 解决问题&#xff1a; 解决方案细节&#xff1a; 解决方案用于目标检测&#xff1a; 即插即用代码&#xff1a; 论文地址&#xff1a; https://arxiv.org…

测试求职个人简历案例参考

当涉及到测试求职个人简历时&#xff0c;关键是突出你在测试领域的技能和经验。以下是一个例子&#xff0c;它包含了简历的常见部分&#xff0c;以突出测试方面的专业知识和个人成就。 基本信息 姓名&#xff1a;XXX 电话&#xff1a;123456789 邮箱&#xff1a;jianli100chui.…

Chromium Mojo(IPC)进程通信演示 c++(3)

122版本自带的mojom通信例子channel-associated-interface 仅供学习参考&#xff1a; codelabs\mojo_examples\03-channel-associated-interface-freezing 其余定义参考上一篇文章&#xff1a; Chromium Mojo(IPC)进程通信演示 c&#xff08;2&#xff09;-CSDN博客​​​​…

如何使用SparkSQL在hive中使用Spark的引擎计算

在hive中&#xff0c;由于hive自带的计算引擎计算比较慢&#xff0c;这个时候可以使用spark替换hive的计算引擎&#xff0c;可以增加hive的计算速度。 在替换之前&#xff0c;首先虚拟机上要有spark的集群模式&#xff0c;spark 的yarn集群模式&#xff0c;需要hdfs&#xff0…

MySQL数据库: 初始MySQL +Navicat (学习笔记)

目录 一&#xff0c;MySQL数据库基本概念 1&#xff0c;数据 2&#xff0c;数据库 3&#xff0c;数据库管理系统 4&#xff0c;数据库应用程序 5&#xff0c;数据库管理员 6&#xff0c;最终用户 7&#xff0c;数据库系统 二&#xff0c;MySQL数据库的分类 1&#xf…

22.04Ubuntu---ROS2创建python节点

创建工作空间 mkdir -p 02_ros_ws/src 然后cd到该目录 创建功能包 在这条命令里&#xff0c;tom就是你的功能包 ros2 pkg create tom --build-type ament_python --dependencies rclpy 可以看到tom功能包已经被创建成功了。 使用tree命令&#xff0c;得到如下文件结构 此时…

多模态大模型技术方向和应用场景

多模态大模型&#xff08;Multimodal Large Language Models&#xff0c;MLLM&#xff09;是一种结合了大型语言模型&#xff08;LLM&#xff09;和大型视觉模型&#xff08;LVM&#xff09;的深度学习模型&#xff0c;它们能够处理和理解多种类型的数据&#xff0c;如文本、图…

力扣 LeetCode 977. 有序数组的平方

解题思路&#xff1a; 方法一&#xff1a;先平方再快排 方法二&#xff1a;双指针 因为可能有负数&#xff0c;所以对于一个数组 [ -5 , -3 , 0 , 2 , 4 ] 可以从两边向内靠拢&#xff0c;最大值一定出现在两端 设置指针 i 和指针 j 分别从左右两边靠拢 因为要从小到大排序…

程序员必备的几款爬虫软件,搞定复杂数据抓取任务

作为一名数据工程师&#xff0c;三天两头要采集数据&#xff0c;用过十几种爬虫软件&#xff0c;也用过Python爬虫库&#xff0c;还是建议新手使用现成的软件比较方便。 这里推荐3款不错的自动化爬虫工具&#xff0c;八爪鱼、亮数据、Web Scraper 1. 八爪鱼爬虫 八爪鱼爬虫是一…

008_SSH_Sqlserverl图书管理系统(学生注册 借书 还书)_lwplus87(免费送)

目 录 Abstract IV 第1章 概述... 1 1.1 课题背景... 1 1.2 课题意义... 1 1.3 文献综述... 2 1.3.1 技术综述... 2 1.4 总体设计原则... 2 第2章 系统分析... 4 2.1 系统的需求分析... 4 2.2 业务流程分析... 5 2.2.1 系统管理员业务流程分析... 5 2.3 数据流程分析... 7 2…

EM是什么?如何修复EM violation?

芯冰乐知识星球入口:芯冰乐 EM就electric-migration,即电迁移。电子在金属导体内迁移时,会与金属原子发生碰撞。时间久了,金属原子便会往电子方向进行移动,导致金属导体发生断裂的现象,我们称之为电迁移现象。 如果金属导体内的电流越大,意味着移动的电子数也就越多。…