java實現(xiàn)SVG圖創(chuàng)建全過程
前言
svg作為矢量圖,如何進(jìn)行結(jié)構(gòu)分析重構(gòu),是很重要的一環(huán),在web開發(fā)中也是比較常見。本文開始介紹如何使用java操作svg圖。
一、SVG是什么?
svg是一種矢量圖,其不會隨著大小變化而失真。
在開發(fā)環(huán)境下,其可以看作一個xml文件,每一個圖形都是可以操作的單位,可以設(shè)置位置、大小、顏色等等。
二、生成一個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);
}
}也可以定義很多其他的子類,比如線條、圓等,這里就兩個舉例。
3. svg面板類
面板可以添加多個形狀
@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實例,然后創(chuàng)建一個空的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é)
本文僅僅介紹了如何生成一個簡單的svg圖,而Apache的Batik還有很多操作svg圖的操作,例如解析一個已有的svg圖,然后進(jìn)行修改等操作,實際應(yīng)用中不會如此簡單的操作。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java 出現(xiàn)問題javax.servlet.http.HttpServlet was not found解決方法
這篇文章主要介紹了java 出現(xiàn)問題javax.servlet.http.HttpServlet was not found解決方法的相關(guān)資料,需要的朋友可以參考下2016-11-11
Spring IoC學(xué)習(xí)之ApplicationContext中refresh過程詳解
這篇文章主要給大家介紹了關(guān)于Spring IoC學(xué)習(xí)之ApplicationContext中refresh過程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
模仿mybatis-plus實現(xiàn)rpc調(diào)用
這篇文章主要為大家介紹了模仿mybatis-plus實現(xiàn)rpc調(diào)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Java中生成隨機(jī)數(shù)的實現(xiàn)方法總結(jié)
這篇文章主要介紹了Java中生成隨機(jī)數(shù)的實現(xiàn)方法總結(jié),其中多線程并發(fā)的實現(xiàn)方式尤為exciting,需要的朋友可以參考下2015-11-11

