java實(shí)現(xiàn)SVG圖創(chuàng)建全過程
前言
svg作為矢量圖,如何進(jìn)行結(jié)構(gòu)分析重構(gòu),是很重要的一環(huán),在web開發(fā)中也是比較常見。本文開始介紹如何使用java操作svg圖。
一、SVG是什么?
svg是一種矢量圖,其不會(huì)隨著大小變化而失真。
在開發(fā)環(huán)境下,其可以看作一個(gè)xml文件,每一個(gè)圖形都是可以操作的單位,可以設(shè)置位置、大小、顏色等等。
二、生成一個(gè)svg圖
1. 引入依賴
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>1.14</version>
</dependency>2. 圖形配置類
2.1 svg圖形基類
@Data
public abstract class ShapeConfig {
protected String id;
protected String type;
protected Map<String, String> attributes;
public ShapeConfig(String type, String id) {
this.type = type;
this.id = id;
}
}attributes主要存一些定義完成屬性之外的一些屬性,后面再具體介紹。
2.2 矩形子類
@Setter
@Getter
public class RectConfig extends ShapeConfig{
private int x;
private int y;
private int width;
private int height;
private String fill = "black";
private String stroke = "none";
private String strokeWidth = "1";
private int rx = 0;
private int ry = 0;
public RectConfig(String id) {
super("rect", id);
}
}父類的attributes則可以存當(dāng)前矩形定義的屬性之外的屬性,例如設(shè)置透明度:
attributes.put("opacity", "0.8");2.3 文本子類
@Setter
@Getter
public class TextConfig extends ShapeConfig{
private int x;
private int y;
private String content;
private String fill = "black";
private String fontFamily = "Arial";
private String fontSize = "16";
public TextConfig(String id) {
super("text", id);
}
}也可以定義很多其他的子類,比如線條、圓等,這里就兩個(gè)舉例。
3. svg面板類
面板可以添加多個(gè)形狀
@Data
public class SvgConfig {
private int width = 400;
private int height = 300;
private String backgroundColor = "white";
private List<ShapeConfig> shapes = new ArrayList<>();
public void addShape(ShapeConfig shape)
{
shapes.add(shape);
}
}4. 創(chuàng)建svg圖
4.1 定義屬性
創(chuàng)建svg面板、矩形、文本,然后創(chuàng)建svg。
public static void main(String[] args) {
try {
// 創(chuàng)建SVG面板配置
SvgConfig config = new SvgConfig();
config.setWidth(500);
config.setHeight(400);
config.setBackgroundColor("#f0f8ff");
// 添加矩形
RectConfig rect1 = new RectConfig("rect1");
rect1.setX(200);
rect1.setY(50);
rect1.setWidth(100);
rect1.setHeight(80);
rect1.setFill("#4ecdc4");
rect1.setStroke("#333");
rect1.setStrokeWidth("2");
rect1.setRx(10);
rect1.setRy(10);
config.addShape(rect1);
// 添加文本
TextConfig text1 = new TextConfig("text1");
text1.setX(100);
text1.setY(300);
text1.setContent("Hello SVG!");
text1.setFill("#1a936f");
text1.setFontFamily("Arial");
text1.setFontSize("20");
config.addShape(text1);
// 生成SVG文件
generateSvg(config, "generated.svg");
} catch (Exception e) {
e.printStackTrace();
}
}4.2 初始化svg的dom
通過DocumentBuilderFactory工廠類創(chuàng)建DocumentBuilder實(shí)例,然后創(chuàng)建一個(gè)空的svg文檔,進(jìn)行文檔的配置以及添加元素,將所有元素添加到文檔中。
- 根元素:所有元素的頂層父元素
- 背景:子元素
- 圖形:子元素
public static void generateSvg(SvgConfig config, String filename) throws Exception {
// 創(chuàng)建空的SVG文檔
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
// 創(chuàng)建SVG根元素
Element svg = doc.createElement("svg");
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
svg.setAttribute("width", String.valueOf(config.getWidth()));
svg.setAttribute("height", String.valueOf(config.getHeight()));
svg.setAttribute("viewBox", "0 0 " + config.getWidth() + " " + config.getHeight());
doc.appendChild(svg);
// 添加背景
if (config.getBackgroundColor() != null && !config.getBackgroundColor().equals("white")) {
Element background = doc.createElement("rect");
background.setAttribute("x", "0");
background.setAttribute("y", "0");
background.setAttribute("width", String.valueOf(config.getWidth()));
background.setAttribute("height", String.valueOf(config.getHeight()));
background.setAttribute("fill", config.getBackgroundColor());
svg.appendChild(background);
}
// 添加圖形元素
for (ShapeConfig shapeConfig : config.getShapes()) {
Element shapeElement = createShapeElement(doc, shapeConfig);
if (shapeElement != null) {
svg.appendChild(shapeElement);
}
}
// 保存SVG文件
saveSvgFile(doc, filename);
System.out.println("SVG文件已生成: " + filename);
}4.3 添加圖形元素
通過config獲取到圖形類,判斷type創(chuàng)建相應(yīng)的元素對象,然后將元素對象添加到根元素中。
private static Element createShapeElement(Document doc, ShapeConfig config) {
Element element = null;
switch (config.getType()) {
case "rect":
element = createRectElement(doc, (RectConfig) config);
break;
case "text":
element = createTextElement(doc, (TextConfig) config);
break;
default:
System.out.println("不支持的圖形類型: " + config.getType());
return null;
}
return element;
}4.4 創(chuàng)建元素對象
矩形元素
private static Element createRectElement(Document doc, RectConfig config) {
Element rect = doc.createElement("rect");
rect.setAttribute("id", config.getId());
rect.setAttribute("x", String.valueOf(config.getX()));
rect.setAttribute("y", String.valueOf(config.getY()));
rect.setAttribute("width", String.valueOf(config.getWidth()));
rect.setAttribute("height", String.valueOf(config.getHeight()));
rect.setAttribute("fill", config.getFill());
if (config.getRx() > 0) {
rect.setAttribute("rx", String.valueOf(config.getRx()));
}
if (config.getRy() > 0) {
rect.setAttribute("ry", String.valueOf(config.getRy()));
}
if (!"none".equals(config.getStroke())) {
rect.setAttribute("stroke", config.getStroke());
rect.setAttribute("stroke-width", config.getStrokeWidth());
}
return rect;
}文本元素
private static Element createTextElement(Document doc, TextConfig config) {
Element text = doc.createElement("text");
text.setAttribute("id", config.getId());
text.setAttribute("x", String.valueOf(config.getX()));
text.setAttribute("y", String.valueOf(config.getY()));
text.setAttribute("fill", config.getFill());
text.setAttribute("font-family", config.getFontFamily());
text.setAttribute("font-size", config.getFontSize());
text.setTextContent(config.getContent());
return text;
}4.5 保存svg文件
通過XML轉(zhuǎn)換器工廠,配置輸出屬性(啟用xml縮進(jìn)、保留xml聲明等),將svg的dom對象輸出到文件中,完成dom到xml文件的轉(zhuǎn)換。
private static void saveSvgFile(Document doc, String filename) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// 設(shè)置輸出屬性
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// 寫入文件
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filename));
transformer.transform(source, result);
}總結(jié)
本文僅僅介紹了如何生成一個(gè)簡單的svg圖,而Apache的Batik還有很多操作svg圖的操作,例如解析一個(gè)已有的svg圖,然后進(jìn)行修改等操作,實(shí)際應(yīng)用中不會(huì)如此簡單的操作。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java處理科學(xué)計(jì)數(shù)法數(shù)字方式
這篇文章主要介紹了Java處理科學(xué)計(jì)數(shù)法數(shù)字方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Maven dependencies與dependencyManagement的區(qū)別詳解
這篇文章主要介紹了Maven dependencies與dependencyManagement的區(qū)別詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04
java圖片驗(yàn)證碼實(shí)現(xiàn)示例分享
這篇文章主要介紹了java實(shí)現(xiàn)圖片驗(yàn)證碼示例,需要的朋友可以參考下2014-02-02
BeanUtils.copyProperties()拷貝id屬性失敗的原因及解決
這篇文章主要介紹了BeanUtils.copyProperties()拷貝id屬性失敗的原因及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Mybatis實(shí)現(xiàn)分頁查詢的詳細(xì)流程
這篇文章主要給大家介紹了關(guān)于Mybatis實(shí)現(xiàn)分頁查詢的詳細(xì)流程,MyBatis是支持普通SQL查詢,存儲(chǔ)過程和高級映射的優(yōu)秀持久層框架,需要的朋友可以參考下2023-08-08

