基于DeepSeek实现PDF嵌入SVG图片无损放大
1. PDF中效果图

2. 询问Deepseek进行代码书写,不断优化后结果
/*** SVG工具类,用于生成价格趋势的SVG图表*/
public class SvgUtils {// SVG画布尺寸private static final int WIDTH = 800;private static final int HEIGHT = 500;private static final int PADDING = 60;// 生成SVG折线图public static String generatePriceTrendSvg(List<PriceData> data, String title, String subtitle) {if (data.isEmpty()) {return "<svg xmlns='http://www.w3.org/2000/svg' width='" + WIDTH + "' height='" + HEIGHT + "'></svg>";}// 计算价格和时间的范围double minPrice = data.stream().mapToDouble(PriceData::getPrice).min().orElse(0) * 0.8;double maxPrice = data.stream().mapToDouble(PriceData::getPrice).max().orElse(1) * 1.2;// 解析最小和最大日期String minYearMonth = data.stream().map(PriceData::getYearmonth).min(String::compareTo).orElse("2024-06");String maxYearMonth = data.stream().map(PriceData::getYearmonth).max(String::compareTo).orElse("2025-01");// 构建SVG内容StringBuilder svg = new StringBuilder();svg.append(String.format("<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>", WIDTH, HEIGHT));// 画背景svg.append(String.format("<rect width='%d' height='%d' fill='#ffffff'/>", WIDTH, HEIGHT));// 添加标题和副标题(居中显示)svg.append(String.format("<text x='%d' y='%d' font-size='20' font-family='Arial' fill='#333333' font-weight='bold' text-anchor='middle'>%s</text>",WIDTH / 2, 30, title));svg.append(String.format("<text x='%d' y='%d' font-size='14' font-family='Arial' fill='#666666' text-anchor='middle'>%s</text>",WIDTH / 2, 50, subtitle));// 画虚线网格线svg.append(drawGrid(minYearMonth, maxYearMonth, minPrice, maxPrice));// 画深色坐标轴svg.append(drawAxis(minYearMonth, maxYearMonth, minPrice, maxPrice));// 画浅色平滑折线svg.append(drawSmoothLine(data, minYearMonth, maxYearMonth, minPrice, maxPrice));svg.append("</svg>");return svg.toString();}// 画虚线网格线private static String drawGrid(String minYearMonth, String maxYearMonth, double minPrice, double maxPrice) {StringBuilder grid = new StringBuilder();// 水平网格线(价格)int numHorizontalLines = 5;for (int i = 0; i <= numHorizontalLines; i++) {double price = minPrice + (maxPrice - minPrice) * i / numHorizontalLines;int y = HEIGHT - PADDING - (int) ((price - minPrice) * (HEIGHT - 2 * PADDING) / (maxPrice - minPrice));grid.append(String.format("<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='#e0e0e0' stroke-width='1' stroke-dasharray='5,5'/>",PADDING, y, WIDTH - PADDING, y));}// 垂直网格线(时间)List<String> yearMonths = generateYearMonths(minYearMonth, maxYearMonth);for (String yearMonth : yearMonths) {int x = PADDING + (int) ((getMonthIndex(yearMonth) - getMonthIndex(minYearMonth)) * (WIDTH - 2 * PADDING) / (yearMonths.size() - 1));grid.append(String.format("<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='#e0e0e0' stroke-width='1' stroke-dasharray='5,5'/>",x, PADDING, x, HEIGHT - PADDING));}return grid.toString();}// 画深色坐标轴private static String drawAxis(String minYearMonth, String maxYearMonth, double minPrice, double maxPrice) {StringBuilder axis = new StringBuilder();// X轴(时间)axis.append(String.format("<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='#333333' stroke-width='2'/>",PADDING, HEIGHT - PADDING, WIDTH - PADDING, HEIGHT - PADDING));// Y轴(价格)axis.append(String.format("<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='#333333' stroke-width='2'/>",PADDING, PADDING, PADDING, HEIGHT - PADDING));// X轴标签List<String> yearMonths = generateYearMonths(minYearMonth, maxYearMonth);for (String yearMonth : yearMonths) {int x = PADDING + (int) ((getMonthIndex(yearMonth) - getMonthIndex(minYearMonth)) * (WIDTH - 2 * PADDING) / (yearMonths.size() - 1));axis.append(String.format("<text x='%d' y='%d' font-size='12' font-family='Arial' fill='#000000' text-anchor='middle'>%s</text>",x, HEIGHT - PADDING + 20, yearMonth));}// Y轴标签int numYLabels = 5;for (int i = 0; i <= numYLabels; i++) {double price = minPrice + (maxPrice - minPrice) * i / numYLabels;int y = HEIGHT - PADDING - (int) ((price - minPrice) * (HEIGHT - 2 * PADDING) / (maxPrice - minPrice));axis.append(String.format("<text x='%d' y='%d' font-size='12' font-family='Arial' fill='#000000' text-anchor='end'>%.2f</text>",PADDING - 10, y + 5, price));}return axis.toString();}// 画浅色平滑折线private static String drawSmoothLine(List<PriceData> data, String minYearMonth, String maxYearMonth, double minPrice, double maxPrice) {if (data.size() < 2) {return "";}StringBuilder path = new StringBuilder("<path d='M");for (int i = 0; i < data.size(); i++) {PriceData point = data.get(i);int x = PADDING + (int) ((getMonthIndex(point.getYearmonth()) - getMonthIndex(minYearMonth)) * (WIDTH - 2 * PADDING) / (getMonthIndex(maxYearMonth) - getMonthIndex(minYearMonth)));int y = HEIGHT - PADDING - (int) ((point.getPrice() - minPrice) * (HEIGHT - 2 * PADDING) / (maxPrice - minPrice));if (i == 0) {path.append(x).append(",").append(y);} else {// 计算控制点以实现平滑效果PriceData prevPoint = data.get(i - 1);int prevX = PADDING + (int) ((getMonthIndex(prevPoint.getYearmonth()) - getMonthIndex(minYearMonth)) * (WIDTH - 2 * PADDING) / (getMonthIndex(maxYearMonth) - getMonthIndex(minYearMonth)));int prevY = HEIGHT - PADDING - (int) ((prevPoint.getPrice() - minPrice) * (HEIGHT - 2 * PADDING) / (maxPrice - minPrice));int ctrlX1 = (prevX + x) / 2;int ctrlY1 = prevY;int ctrlX2 = (prevX + x) / 2;int ctrlY2 = y;path.append(" C").append(ctrlX1).append(",").append(ctrlY1).append(" ").append(ctrlX2).append(",").append(ctrlY2).append(" ").append(x).append(",").append(y);}}path.append("' fill='none' stroke='#66B3FF' stroke-width='2'/>");return path.toString();}// 生成从 minYearMonth 到 maxYearMonth 的连续月份列表private static List<String> generateYearMonths(String minYearMonth, String maxYearMonth) {List<String> yearMonths = new ArrayList<>();int year = Integer.parseInt(minYearMonth.substring(0, 4));int month = Integer.parseInt(minYearMonth.substring(5));while (true) {yearMonths.add(String.format("%04d-%02d", year, month));if (yearMonths.get(yearMonths.size() - 1).equals(maxYearMonth)) {break;}month++;if (month > 12) {month = 1;year++;}}return yearMonths;}// 将 yearmonth 转换为索引(从 0 开始)private static int getMonthIndex(String yearMonth) {int year = Integer.parseInt(yearMonth.substring(0, 4));int month = Integer.parseInt(yearMonth.substring(5));return (year - 2024) * 12 + (month - 1); // 假设最小年份是 2024}public static void main(String[] args) {List<PriceData> data = PriceData.getSampleData();String title = "价格走势图";String subtitle = "2024-06 至 2025-01";String svg = SvgUtils.generatePriceTrendSvg(data, title, subtitle);System.out.println(svg);}
}
@Data
public class PriceData {private String yearmonth;private Double price;public PriceData() {}public PriceData(String yearmonth, Double price) {this.yearmonth = yearmonth;this.price = price;}public static List<PriceData> getSampleData() {List<PriceData> data = new ArrayList<>();data.add(new PriceData("2025-01", 100.0)); // 2023-01-01data.add(new PriceData("2025-02", 105.0)); // 2023-01-02data.add(new PriceData("2025-03", 102.0)); // 2023-01-03data.add(new PriceData("2025-04", 110.0)); // 2023-01-04data.add(new PriceData("2025-05", 108.0)); // 2023-01-05return data;}
}
OK, 生成的SVG嵌入到html网页中进行渲染即可
相关文章:
基于DeepSeek实现PDF嵌入SVG图片无损放大
1. PDF中效果图 2. 询问Deepseek进行代码书写,不断优化后结果 /*** SVG工具类,用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…...
整型的不同类型和溢出
一、整数的不同类型 不同编程语言中的整数类型主要通过以下两个维度区分: 1. 存储大小 字节数:决定整数能表示的范围(如 1字节8位)。 常见类型: byte(1字节)、short(2字节&#x…...
使用express创建服务器保存数据到mysql
创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…...
小程序 wxml 语法 —— 41列表渲染 - 进阶用法
这一节讲解列表渲染的两个进阶用法: 如果需要对默认的变量名和下标进行修改,可以使用 wx:for-item 和 wx:for-item: 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…...
python语言总结(持续更新)
本文主要是总结各函数,简单的函数不会给予示例,如果在平日遇到一些新类型将会添加 基础知识 输入与输出 print([要输出的内容])输出函数 input([提示内容]如果输入提示内容会在交互界面显示,用以提示用户)输入函数 注释 # 单行注释符&…...
正则表达式简述
普通字符 普通字符代表它们自身,用于精确匹配字符串中的字符。例如,a 匹配字符 a,1 匹配数字 1。元字符 元字符是具有特殊含义的字符,用于匹配特定类型的字符或字符串模式。 常用元字符 . :匹配除换行符以外的任意单个…...
FPGA学习篇——Verilog学习5(reg,wire区分及模块例化)
1 何时用reg,何时用wire? 这个我找了一些网上的各种资料,大概说一下自己的理解,可能还不太到位... wire相当于一根线,是实时传输的那种,而reg是一个寄存器,是可以存储数据的,需要立…...
Redis 数据持久化之AOF
AOF(Append Only File) 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换…...
【芯片验证】verificationguide上的74道SystemVerilog面试题
诧异啊,像我这种没事在网上各处捡东西吃的人为什么之前一直没有用过verificationguide这个网站呢?总不能是大家都已经看过就留下我不知道吧。前几天在论坛上和朋友谈论验证面试题时才搜到这个网站的,感觉挺有意思: .: Verification Guide :.verificationguide.com/https…...
C++进阶知识10 封装unordered_map和unordered_set
封装unordered_map和unordered_set 1. 模拟实现unordered_map和unordered_set1.1 实现出复⽤哈希表的框架,并⽀持insert 1. 模拟实现unordered_map和unordered_set 1.1 实现出复⽤哈希表的框架,并⽀持insert • 参考源码框架,unordered_map…...
大白话JavaScript数据类型判断方法的原理与实践
大白话JavaScript数据类型判断方法的原理与实践 答题思路 明确 JavaScript 数据类型:JavaScript 数据类型分为基本数据类型(如 Number、String、Boolean、Null、Undefined、Symbol)和引用数据类型(如 Object、Array、Function 等…...
Java后端高频面经——计算机网络
TCP/IP四层模型?输入一个网址后发生了什么,以百度为例?(美团) (1)四层模型 应用层:支持 HTTP、SMTP 等最终用户进程传输层:处理主机到主机的通信(TCP、UDP&am…...
面试题(二)--Object中的常见方法
Object Java的Object是所有Java类的父类,所有的Java类直接或者间接的继承了Object类,Object类位于java.lang包中(编译时自动导入),主要提供了11种方法。 /*** native 方法,用于返回当前运行时对象的 Class…...
运行OpenManus项目(使用Conda)
部署本项目需要具备一定的基础:Linux基础、需要安装好Anaconda/Miniforge(Python可以不装好,直接新建虚拟环境的时候装好即可),如果不装Anaconda或者Miniforge,只装过Python,需要确保Python是3.…...
如何在 Windows 10 启用卓越性能模式及不同电源计划对比
在使用 powercfg -duplicatescheme 命令启用 “卓越性能模式”(即 Ultimate Performance 模式)之前,有几个前提条件需要注意: 前提条件: 系统版本要求:卓越性能模式 仅在 Windows 10 专业版 或更高版本&a…...
设备管理系统功能与.NET+VUE(IVIEW)技术实现
在现代工业和商业环境中,设备管理系统(Equipment Management System,简称EMS)是确保设备高效运行和维护的关键工具。本文采用多租户设计的设备管理系统,基于.NET后端和VUE前端(使用IVIEW UI框架)…...
分布式光伏发电的发展现状与前景
分布式光伏发电的发展现状与前景 1、分布式光伏发电的背景2、分布式光伏发电的分类2.1、集中式光伏发电2.1.1、特点、原则2.1.2、优点2.1.3、缺点 2.2、分布式光伏发电2.2.1、特点、原则2.2.2、优点2.2.3、缺点 2.3、对比 3、分布式光伏发电的现状4、分布式光伏发电的应用场景4…...
数据类设计_图片类设计之2_无规则图类设计(前端架构基础)
前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇数据类设计_图片类设计之1_矩阵类设计(前端架构基础)-CSDN博客,讨论非规则图类型的设计 无规则图的简单定义 前面的矩阵类,有明显的特征:长,宽,行和…...
aws(学习笔记第三十二课) 深入使用cdk(API Gateway + event bridge)
文章目录 aws(学习笔记第三十二课) 深入使用cdk学习内容:1. 使用aws API Gatewaylambda1.1. 以前的练习1.2. 使用cdk创建API Gateway lambda1.3. 确认cdk创建API Gateway lambda 2. 使用event bridge练习producer和consumer2.1. 代码链接2.2. 开始练习2.3. 代码部…...
计算机视觉算法实战——老虎个体识别(主页有源码)
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 1. 领域介绍 老虎个体识别是计算机视觉中的一个重要应用领域,旨在通过分析老虎的独特条纹图案,自动识别和区…...
Qt添加MySql数据库驱动
文章目录 一. 安装MySql二.编译mysql动态链接库 Qt版本:5.14.2 MySql版本:8.0.41 一. 安装MySql 参考这里进行安装:https://blog.csdn.net/qq_30150579/article/details/146042922 将mysql安装目录里的bin,include和lib拷贝出来…...
蓝桥杯备考:图论初解
1:图的定义 我们学了线性表和树的结构,那什么是图呢? 线性表是一个串一个是一对一的结构 树是一对多的,每个结点可以有多个孩子,但只能有一个父亲 而我们今天学的图!就是多对多的结构了 V表示的是图的顶点集…...
【每日学点HarmonyOS Next知识】输入框自动获取焦点、JS桥实现方式、Popup设置全屏蒙版、鼠标事件适配、Web跨域
1、HarmonyOS TextInput或TextArea如何自动获取焦点? 可以使用 focusControl.requestFocus 对需要获取焦点的组件设置焦点,具体可以参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attribut…...
网络空间安全(19)CSRF攻防
一、简介 跨站请求伪造(Cross-Site Request Forgery,简称CSRF)是一种网络攻击方式。攻击者通过诱导受害者访问恶意页面,利用受害者在被攻击网站已经获取的注册凭证(如Cookie),绕过后台的用户验证…...
Unity大型游戏开发全流程指南
一、开发流程与核心步骤 1. 项目规划与设计阶段 需求分析 明确游戏类型(MMORPG/开放世界/竞技等)、核心玩法(战斗/建造/社交)、目标平台(PC/移动/主机)示例:MMORPG需规划角色成长树、副本Boss…...
[mybatis]resultMap详解
resultMap Mybatis中提供了resultMap功能,可以将数据库查询结果映射到Java对象,用于解决 字段名与属性名不一致 或 复杂关系(如一对多)的映射问题。 比如一个User类,在它的属性里还有另一个子对象(或者多…...
DEV C++安装
点击----我接受 点击--下一步 选择安装路径: D盘安装选择路径: 点击----安装等待安装完成点击---完成即可 一路下一步即可...
ESP32驱动OV3660摄像头实现物体轮廓识别(摄像头支持红外夜视、边缘AI计算)
目录 1、传感器特性 2、硬件原理图 3、驱动程序 ESP32-S3 AI智能摄像头模块是一款专为智能家居和物联网应用打造的高性能边缘AI开发模组。它集成了摄像头、麦克风、音频功放、环境光传感器和夜视补光灯,无需依赖云端即可实现本地化AI推理。 凭借TensorFlow Lite、YOLO和O…...
深入探讨 Docker 层次结构及其备份策略20250309
深入探讨 Docker 层次结构及其备份策略 本文将深入探讨 Docker 层次结构 以及在 不同场景下应选择哪种备份方式。通过本文的介绍,您将对如何高效地管理和迁移 Docker 容器有更深的理解。 📌 什么是 Docker 层次结构? Docker 镜像采用了 分…...
游戏引擎学习第145天
仓库:https://gitee.com/mrxiao_com/2d_game_3 今天的计划 目前,我们正在完成遗留的工作。当时我们已经将声音混合器(sound mixer)集成到了 SIMD 中,但由于一个小插曲,没有及时完成循环内部的部分。这个小插曲主要是…...
