基于Java的不固定长度字符集在指定宽度和自适应模型下图片绘制生成实战

目录

前言

一、需求介绍

1、指定宽度生成

2、指定列自适应生成

二、Java生成实现

1、公共方法

2、指定宽度生成

3、指定列自适应生成

三、总结


前言

        在当今数字化与信息化飞速发展的时代,图像的生成与处理技术正日益成为众多领域关注的焦点。从创意设计到数据可视化,从游戏开发到人工智能辅助创作,高效、精准且具有高度适应性的图像生成方案有着广泛而迫切的需求。Java 作为一种强大、稳定且广泛应用的编程语言,在图像绘制领域也发挥着不可忽视的作用。

        在GIS领域,比如图例的生成就会面对以上的问题。由于在进行字符标注时无法预测文本的长度,因此我们需要能有一种自适应文本长度的生成方法,但是同时,也有可能我们需要指定一种宽度从而对字符文本进行绘制的需要。如下两图所示:

自适应宽度生成示意图

指定宽度生成示意图 

        本实战旨在深入探讨基于 Java 的不固定长度字符集在指定宽度和自适应模型下图片绘制生成的方法与技巧。不固定长度字符集为图片绘制带来了独特的挑战与机遇。一方面,其灵活多变的字符组合方式能够创造出丰富多样、极具个性化的图像效果,为创意表达提供了广阔空间;另一方面,如何在保证图像整体协调性与美观性的前提下,合理安排不同长度字符在指定宽度内的布局,实现自适应模型下的高效绘制,需要深入研究与实践。

        通过本次实战,我们期望为读者提供一套完整、实用且具有创新性的基于 Java 的图片绘制解决方案,帮助读者提升在图像生成领域的技术能力,激发他们在数字创作方面的灵感与潜力,从而在各自的应用场景中创造出更具价值与吸引力的图像作品,为推动图像技术的发展与应用贡献一份力量。

一、需求介绍

        在面向地理空间的图例生成过程,我们通常会遇到以下两种情况:第一种是需要指定宽度,比如要求在宽度为200px的图片中,将指定的文字在图片中生成。第二种就是需要根据指定列,即一行展示几列,然后自适应的生成固定宽度的图片。本节将主要介绍这两个需求。这里我们需要展示的是一些不一定长的字符串集合,模拟展示以下这些地名数据,如下所示:

String[] demoTexts = {" 项目管理", "软件开发", "数据分析","人工智能", "云计算", "网络安全","用户体验", "测试验证", "运维部署", "昆明市","曲靖市","玉溪市","保山市","昭通市","丽江市","普洱市","临沧市","楚雄彝族自治州","红河哈尼族彝族自治州","文山壮族苗族自治州","西双版纳傣族自治州","湘西土家族苗族自治州","深圳市","保亭黎族苗族自治县","阿坝藏族羌族自治州","黔西南布依族苗族自治州","克孜勒苏柯尔克孜自治州","双江拉祜族佤族布朗族傣族自治县","积石山保安族东乡族撒拉族自治县","中国石油集团东方地球物理勘探有限责任公司霸州基地管理处居委会","天津市蓟州区京津州河科技产业园管理委员会虚拟社区","窑街煤电集团民勤县瑞霖生态农林有限责任公司生活区","沈阳市于洪区红旗土地股份合作经营有限公司生活区","大理白族自治州","德宏傣族景颇族自治州","怒江傈僳族自治州","迪庆藏族自治州"
};

1、指定宽度生成

        指定宽度生成,即我们对目标成果的图片宽度是有要求的,比如宽度指定为200px。核心需求如下:

        固定总宽度模式

  • 平均分配列宽:根据总宽度和列数计算每列可用宽度

  • 自动换行:根据列数自动计算行数

  • 文本截断:超长文本添加省略号

2、指定列自适应生成

        自适应列宽模式

  • 动态计算列宽:根据每列中最长的条目确定列宽,遍历所有文本,计算每个条目(矩形+间距+文本)的总宽度,确定最大宽度作为图像宽度。

  • 计算高度:基于行数和字体高度计算总高度

  • 自动换行:根据列数自动计算行数

  • 保持完整显示:不截断文本

二、Java生成实现

        本小节将根据上面的生成需求来具体讲解如何进行详细的生成。java生成的实现分成三个部分,第一部分是介绍两个公共方法,第二部分介绍如何按照指定宽度生成,第三部分介绍如何进行自适应生成,通过代码实例的方法进行讲解。

1、公共方法

        为了方便对对绘制的文字展示得更加美观,这里我们每进行一次绘制就修改画笔的颜色。因此需要一个生成指定颜色的方法,在java中生成Color对象,并且转为十六进制的颜色表示,核心方法如下:

/**
* - 将color转十六进制字符串
* @param color
* @return
*/
public static String Color2String(Color color) {// 获取 RGB 颜色值,格式为 0x00RRGGBBint rgb = color.getRGB();// 将 RGB 转换为十六进制字符串,去掉前两位的透明度部分(如果是纯不透明颜色)String hexColor = "#" + Integer.toHexString(rgb & 0xffffff);return hexColor;
}

        根据不同字符串生成均匀分布的颜色方法如下:

// 生成可区分颜色(HSV色环均匀分布)
private static Color[] generateDistinctColors(int count) {Color[] colors = new Color[count];float goldenRatio = 0.618033988749895f;  // 黄金分割比例float saturation = 0.8f;  // 饱和度float brightness = 0.9f;  // 亮度for (int i = 0; i < count; i++) {float hue = (i * goldenRatio) % 1.0f;colors[i] = Color.getHSBColor(hue, saturation, brightness);}return colors;
}

         以上两个方法在指定宽度生成和自适应生成中均会使用到,因此在此简单列出来。

2、指定宽度生成

按指定宽度生成的核心方法如下:

// 固定总宽度模式
public static BufferedImage createFixedColumnsImage(String[] texts, int columns,int totalWidth, Font font,int padding, int columnSpacing,int rowSpacing) {BufferedImage tempImg = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);Graphics2D tempG = tempImg.createGraphics();tempG.setFont(font);FontMetrics fm = tempG.getFontMetrics();final int RECT_SIZE = 10;final int ENTRY_SPACING = 5;// 生成颜色序列Color[] colors = generateDistinctColors(texts.length);// 计算列宽int availableWidth = totalWidth - padding * 2 - (columns - 1) * columnSpacing;int columnWidth = availableWidth / columns;int textMaxWidth = columnWidth - RECT_SIZE - ENTRY_SPACING;// 处理文本List<String> processedTexts = new ArrayList<>();for (String text : texts) {processedTexts.add(truncateText(text, textMaxWidth, fm));}// 计算总高度int rows = (int) Math.ceil((double)texts.length / columns);int totalHeight = padding * 2 + rows * (fm.getHeight() + rowSpacing) - rowSpacing;// 创建图像BufferedImage image = new BufferedImage(totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D g = image.createGraphics();setupGraphics(g, font);// 绘制背景g.setColor(Color.WHITE);g.fillRect(0, 0, totalWidth, totalHeight);// 绘制条目int yBase = padding + fm.getAscent();int[] columnX = new int[columns];for (int i = 0; i < columns; i++) {columnX[i] = padding + i * (columnWidth + columnSpacing);}for (int i = 0; i < processedTexts.size(); i++) {g.setColor(colors[i]);int col = i % columns;int row = i / columns;int y = yBase + row * (fm.getHeight() + rowSpacing);int rectY = y - fm.getAscent() + (fm.getHeight() - RECT_SIZE)/2;// 绘制矩形g.fillRect(columnX[col], rectY, RECT_SIZE, RECT_SIZE);// 绘制文本g.drawString(processedTexts.get(i), columnX[col] + RECT_SIZE + ENTRY_SPACING, y);}g.dispose();tempG.dispose();return image;
}

        由于在指定宽度的生成方式中,绘制的图片宽度是固定的,而文字的字数是不固定的。因此在绘制的过程中,需要对超长的文本进行截取,超长的部分将使用省略号来进行展示。对超长文本字符进行截断处理的方法如下:

private static String truncateText(String text, int maxWidth, FontMetrics fm) {if (fm.stringWidth(text) <= maxWidth) return text;int ellipsisWidth = fm.stringWidth("...");int availableWidth = maxWidth - ellipsisWidth;int length = text.length();while (length > 0 && fm.stringWidth(text.substring(0, length)) > availableWidth) {length--;}return length > 0 ? text.substring(0, length) + "..." : "";
}

         生成指定宽度的图片调用方法如下:

// 生成固定宽度图片(400px宽,2列)
BufferedImage fixedImage = createFixedColumnsImage(demoTexts, 2, 400,new Font("宋体", Font.PLAIN, 12),15, 20, 10
);
ImageIO.write(fixedImage, "PNG", new File("D:/fixed_columns_250420.png"));

        生成的成果图片如下:

3、指定列自适应生成

        生成指定列的自适应图片生成的核心方法如下:

// 自适应列宽模式public static BufferedImage createAdaptiveColumnsImage(String[] texts, int columns,Font font, int padding, int columnSpacing, int rowSpacing) {BufferedImage tempImg = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);Graphics2D tempG = tempImg.createGraphics();tempG.setFont(font);FontMetrics fm = tempG.getFontMetrics();final int RECT_SIZE = 10;final int ENTRY_SPACING = 5; // 图标与文字间距// 生成颜色序列Color[] colors = generateDistinctColors(texts.length);int index = 0;for (String text : texts) {texts[index] = Color2String(colors[index]) + " " + text; //processedTexts.add(truncateText(text, textMaxWidth, fm));index ++;}// 计算列宽int[] columnWidths = new int[columns];for (int i = 0; i < texts.length; i++) {int col = i % columns;int width = RECT_SIZE + ENTRY_SPACING + fm.stringWidth(texts[i]);if (width > columnWidths[col]) {columnWidths[col] = width;}}// 计算总尺寸int totalWidth = padding * 2;for (int w : columnWidths) {totalWidth += w + columnSpacing;}totalWidth -= columnSpacing; // 最后一列不加间距int rows = (int) Math.ceil((double)texts.length / columns);int totalHeight = padding * 2 + rows * (fm.getHeight() + rowSpacing) - rowSpacing;// 创建图像BufferedImage image = new BufferedImage(totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D g = image.createGraphics();setupGraphics(g, font);// 绘制背景g.setColor(Color.WHITE);g.fillRect(0, 0, totalWidth, totalHeight);// 绘制条目int x = padding;int yBase = padding + fm.getAscent();int[] columnX = new int[columns];for (int i = 0; i < columns; i++) {columnX[i] = x;x += columnWidths[i] + columnSpacing;}g.setColor(Color.RED);for (int i = 0; i < texts.length; i++) {g.setColor(colors[i]);int col = i % columns;int row = i / columns;int y = yBase + row * (fm.getHeight() + rowSpacing);int rectY = y - fm.getAscent() + (fm.getHeight() - RECT_SIZE)/2;// 绘制矩形g.fillRect(columnX[col], rectY, RECT_SIZE, RECT_SIZE);// 绘制文本g.drawString(texts[i], columnX[col] + RECT_SIZE + ENTRY_SPACING, y);}g.dispose();tempG.dispose();return image;}

        在自适应生成的过程中,最需要处理的逻辑就是动态的计算宽度等值。最终生成的结果图片如下:

三、总结

        以上就是本文的主要内容,本实战旨在深入探讨基于 Java 的不固定长度字符集在指定宽度和自适应模型下图片绘制生成的方法与技巧。不固定长度字符集为图片绘制带来了独特的挑战与机遇。一方面,其灵活多变的字符组合方式能够创造出丰富多样、极具个性化的图像效果,为创意表达提供了广阔空间;另一方面,如何在保证图像整体协调性与美观性的前提下,合理安排不同长度字符在指定宽度内的布局,实现自适应模型下的高效绘制,需要深入研究与实践。

        通过本次实战,我们期望为读者提供一套完整、实用且具有创新性的基于 Java 的图片绘制解决方案,帮助读者提升在图像生成领域的技术能力,激发他们在数字创作方面的灵感与潜力,从而在各自的应用场景中创造出更具价值与吸引力的图像作品,为推动图像技术的发展与应用贡献一份力量。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

        完整的代码链接如下:Java根据字符串集合生成固定宽度和自适应宽度源码。

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

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

相关文章

软考 系统架构设计师系列知识点之杂项集萃(93)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;92&#xff09; 第169题 人工智能技术已成为当前国际科技竞争的核心技术之一&#xff0c;AI芯片是占据人工智能市场的法宝。AI芯片有别于通常处理器芯片&#xff0c;它应具备四种关键特征。&…

Kotlin实现文件下载断点续传(RandomAccessFile全解析)

本文将深入探讨如何使用Kotlin和RandomAccessFile实现高效的断点续传功能&#xff0c;涵盖原理分析、完整代码实现、性能优化及工程实践要点。 一、断点续传核心原理 1.1 HTTP断点续传协议 #mermaid-svg-EfmgPUx3SFkso8Fc {font-family:"trebuchet ms",verdana,aria…

linux-headers-$(uname -r)和kmod是什么?

2025年6月16日&#xff0c;周一清晨 Linux-headers-$(uname -r)与kmod包详解 一、linux-headers-$(uname -r)包 linux-headers-(uname -r)是Linux系统中与当前运行内核版本匹配的内核头文件包&#xff0c;其中(uname -r)会自动替换为当前内核版本号&#xff08;如5.13.0-19-g…

使用axios及和spirng boot 交互

Axios Axios是一个基于Promise的HTTP库&#xff0c;可以发送get、post等请求&#xff0c;它作用于浏览器和Node.js中。当运行在浏览器时&#xff0c;使用XMLHttpRequest接口发送请求&#xff1b;当运行在Node.js时&#xff0c;使用HTTP对象发送请求。 使用步骤&#xff1a; 第…

布局文件的逐行详细解读

总览 源码 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto&…

VTK 显示大量点云数据及交互(点云拾取、着色、测量等)功能

VTK (Visualization Toolkit) 是一个强大的开源可视化库&#xff0c;非常适合处理点云数据。下面将介绍如何使用 VTK 显示大量点云数据&#xff0c;并实现点云拾取、着色、测量等功能。 基本点云显示 创建一个基本的点云显示程序&#xff1a; cpp #include <vtkSmartPoi…

性能优化 - 高级进阶: 性能优化全方位总结

文章目录 Pre1. 概述&#xff1a;性能优化提纲与使用场景2. 准备阶段2.1 明确优化范围与目标2.2 环境与工具准备 3. 数据收集与指标确认3.1 关键资源维度与指标项3.2 监控体系搭建与初始采集3.3 日志与追踪配置 4. 问题定位思路4.1 从整体到局部的分析流程4.2 常见瓶颈维度检查…

Mybatis之Integer类型字段为0,入库为null

背景&#xff1a; 由于项目某个功能用到优先级字段来判断&#xff0c;需要在mysql表中定义一个字段XX&#xff0c;类型为int&#xff0c;默认为0&#xff0c;具体值由后台配置&#xff0c;正常入库即可 问题&#xff1a; 由于后台配置存量其他类型的数据无需该字段&#xff0c…

上海市计算机学会竞赛平台2022年3月月赛丙组洗牌

题目描述 给定一个整数 nn&#xff0c;表示 nn 张牌&#xff0c;牌的编号为 11 到 nn。 再给定一个洗牌置换 f1,f2,…,fnf1​,f2​,…,fn​&#xff0c;进行一次洗牌操作时&#xff0c;应将第一号位置的牌交换到第 f1f1​ 号位置&#xff0c;将第 ii 号位置的牌交换到第 fifi…

DINO-R1:激励推理能力的视觉基础模型

摘要 近期&#xff0c;人们对大型语言模型&#xff08;如DeepSeek-R1&#xff09;推理能力的关注呈爆炸式增长&#xff0c;通过基于强化学习的微调框架&#xff08;如组相对策略优化&#xff08;Group Relative Policy Optimization&#xff0c;GRPO&#xff09;方法&#xff…

Linux--LVM逻辑卷扩容

Linux–LVM逻辑卷扩容 文章目录 Linux--LVM逻辑卷扩容📚 LVM 常用命令分类及基本格式✅ 1. 物理卷(PV)相关命令✅ 2. 卷组(VG)相关命令✅ 3. 逻辑卷(LV)相关命令🔍 三、查看类命令简写说明使用命令及基本格式:lvm逻辑卷扩容步骤:1.添加硬盘设备2.检测新增硬盘 添加…

C#基础语法与控制台操作

1. 控制台操作基础 控制台程序是学习C#的起点。以下是一些常用的控制台操作方法&#xff1a; 1.1. 清除控制台 Console.Clear(); // 清除控制台内容1.2. 输出字符串 Console.WriteLine("Hello World!"); // 在屏幕的当前位置换行输出字符串 Console.Write("…

100.Complex[]同时储存实数和虚数两组double的数组 C#例子

在信号处理中&#xff0c;IQ 数据&#xff08;In-phase and Quadrature&#xff09;通常表示复数形式的信号&#xff0c;其中实部表示同相分量&#xff0c;虚部表示正交分量。Complex[] data 是一个包含 IQ 数据的数组&#xff0c;每个元素是一个复数&#xff0c;表示一个信号样…

停止追逐 React 重渲染

大多数开发者都在浪费时间对抗多余的重渲染。真正的 React 架构师根本让问题无从产生——下面就来揭开他们的思路&#xff0c;以及为何大多数所谓的性能优化技巧反而拖慢了你的应用。 重渲染的无尽轮回 先来直击痛点&#xff1a;如果还在项目里到处撒 useMemo、useCallback&…

流水线的安全与合规 - 构建可信的交付链

流水线的安全与合规 - 构建可信的交付链 “安全左移 (Shift-Left Security)”的理念 “安全左移”是 DevSecOps 的核心理念,指的是将安全测试和考量,从软件开发生命周期 (SDLC) 的末端(发布前),尽可能地向左移动到更早的阶段(如编码、构建、测试阶段)。 为何对 SRE 至…

​​​​​​​神经网络基础讲解 一

​​一.神经网络 ​ ​​1. 全连接神经网络&#xff08;Fully Connected Network, FCN&#xff09;​​ ​​核心概念&#xff1a;​​ ​​输入层​​&#xff1a;接收原始数据&#xff08;如数字、图片像素等&#xff09; 数字矩阵 。​​隐藏层​​&#xff1a;对数据…

MySQL 8.0 OCP 英文题库解析(二十二)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题201~210 试题2…

【大模型推理】PD分离场景下decoder负载均衡,如何选取decoder

https://mp.weixin.qq.com/s?__bizMzg4NTczNzg2OA&mid2247507420&idx1&sn4b32726abd205c7f94144bcb9105330f&chksmce64b9fc7f1d8de04a40b0153302dee52262c6f104c67195e2586e75c8093b8be493f252c8a3#rd 在非 Local 场景下&#xff0c;Prefill 定时获取 Decode …

【IP地址】IP应用场景的使用方向

网络安全领域 通过IP地址查询&#xff0c;安全系统能够实时监控网络流量&#xff0c;识别异常访问行为。例如&#xff0c;当某个IP地址在短时间内频繁发起大量请求&#xff0c;且访问模式与正常用户存在明显差异时&#xff0c;系统可将其标记为可疑IP&#xff0c;触发风险预警…

3-18 WPS JS宏 颜色设置实例应用(按条件设置单元格颜色)学习笔记

前面讲解了关于单元格的一些格式的设置&#xff0c;本节课再讲解一下各种清除方法。 1.函数解析与用法 Range().clear()//清除全部 Range().Value2null //清除内容 Range().ClearContents()//清除内容 Range().ClearFormats()//清除格式 Range().EntireRow.Range()//以Ra…