SVG Generator: SVGGraphics2D
Java程序可以将图形绘制为SVG,然后在任何SVG查看器中查看,本文主要解释了Batik的SVGGraphics2D(即SVG生成器,)是如何实现这一点的。
On the Java platform, all rendering goes through the Graphics2D abstract class, which offers methods such as drawRect, fillRect, and drawString. There are specialized implementations of this abstract class for each type of output, such as a screen or a printer. SVGGraphics2D is a new implementation of that interface that generates SVG content instead of drawing to a screen or a printer.
在Java平台上,所有的显示都通过Graphics2D抽象类实现,该类提供了drawRect、fillRect和drawString等方法。对于每种输出类型(如屏幕或打印机),都由这个抽象类的专用实现。SVGGraphics2D是Graphics2D接口的的新实现,它将绘制内容生成SVG内容,而不是绘制到屏幕或打印机上。
SVGGraphics2D 具有以下特点:
<!--[if !supportLists]-->· <!--[endif]-->将图形导出为SVG格式
<!--[if !supportLists]-->· <!--[endif]-->不需要修改任何代码直接输出为SVG文档
<!--[if !supportLists]-->· <!--[endif]-->为用户提供使用 DOM API 操作SVG文档
W3C已经定义了一个用于用Java对象表示XML内容的DOM API 。允许程序员在内存中操作、创建和/或修改XML内容。DOM API包含Document、Element和Attr等接口,这些接口为Java编程语言建模,相当于XML文档、元素和属性。
生成器管理DOM对象树,这些对象表示SVG内容,对应于对SVGGraphics2D实例进行的呈现调用。换句话说,每当程序在SVGGraphics2D实例上调用一个渲染操作方法(比如fillRect)时,一个表示SVG的新DOM对象就会被追加到DOM树中。例如,一个rect元素在fillRect方法被调用后追加到DOM中)。
Shape shape=new Rectangle(10, 10, 100, 100);
SVGGraphics2D.setPaint(Color.red);
SVGGraphics2D.fill(shape);//同时操作了DOM
然后,程序员可以使用这个生成器访问DOM树进一步操作它,或者直接将内容写入输出流,如下一节所示。
DOM树是SVG文档的内存表示,用户可以使用DOM API进一步操作它,也可以由Writer对象输出。下面的示例程序演示了如使用生成器生成SVG内容。.
importjava.awt.Rectangle;
importjava.awt.Graphics2D;
importjava.awt.Color;
importjava.io.Writer;
importjava.io.OutputStreamWriter;
importjava.io.IOException;
importorg.apache.batik.svggen.SVGGraphics2D;
importorg.apache.batik.dom.GenericDOMImplementation;
importorg.w3c.dom.Document;
importorg.w3c.dom.DOMImplementation;
publicclassTestSVGGen{
publicvoidpaint(Graphics2D g2d){
g2d.setPaint(Color.red);
g2d.fill(new Rectangle(10,10,100,100));
}
publicstaticvoidmain(String[] args)throws IOException {
// Get a DOMImplementation.
DOMImplementation domImpl =
GenericDOMImplementation.getDOMImplementation();
// Create an instance of org.w3c.dom.Document.
String svgNS ="http://www.w3.org/2000/svg";
Document document = domImpl.createDocument(svgNS,"svg",null);
// Create an instance of the SVG Generator.
SVGGraphics2D svgGenerator =new SVGGraphics2D(document);
// Ask the test to render into the SVG Graphics2D implementation.
TestSVGGen test =new TestSVGGen();
test.paint(svgGenerator);
// Finally, stream out SVG to the standard output using
// UTF-8 encoding.
boolean useCSS =true;// we want to use CSS style attributes
Writer out =new OutputStreamWriter(System.out,"UTF-8");
svgGenerator.stream(out, useCSS);
}
}
TestSVGGen实例通过3个步骤创建SVG内容
<!--[if !supportLists]-->1. <!--[endif]-->创建 org.w3c.dom.Document实例,再通过 Document 实例创建SVG 生成器svgGenerator.
<!--[if !supportLists]-->2. <!--[endif]-->// Get a DOMImplementation.
<!--[if !supportLists]-->3. <!--[endif]-->DOMImplementation domImpl =
<!--[if !supportLists]-->4. <!--[endif]--> GenericDOMImplementation.getDOMImplementation();
<!--[if !supportLists]-->5. <!--[endif]-->
<!--[if !supportLists]-->6. <!--[endif]-->// Create an instance of org.w3c.dom.Document.
<!--[if !supportLists]-->7. <!--[endif]-->String svgNS ="http://www.w3.org/2000/svg";
<!--[if !supportLists]-->8. <!--[endif]-->Document document = domImpl.createDocument(svgNS,"svg",null);
<!--[if !supportLists]-->9. <!--[endif]-->
<!--[if !supportLists]-->10.<!--[endif]-->// Create an instance of the SVG Generator.
<!--[if !supportLists]-->11.<!--[endif]-->SVGGraphics2D svgGenerator =new SVGGraphics2D(document);
<!--[if !supportLists]-->12. <!--[endif]-->通过生成器调用渲染代码:
<!--[if !supportLists]-->13.<!--[endif]-->// Ask the test to render into the SVG Graphics2D implementation.
<!--[if !supportLists]-->14.<!--[endif]-->TestSVGGen test =new TestSVGGen();
<!--[if !supportLists]-->15.<!--[endif]-->test.paint(svgGenerator);
<!--[if !supportLists]-->16. <!--[endif]-->输出SVG内容,生成器可以调用任何输入输出流输出内容:
<!--[if !supportLists]-->17.<!--[endif]-->// Finally, stream out SVG to the standard output using
<!--[if !supportLists]-->18.<!--[endif]-->// UTF-8 encoding.
<!--[if !supportLists]-->19.<!--[endif]-->boolean useCSS =true;// we want to use CSS style attributes
<!--[if !supportLists]-->20.<!--[endif]-->Writer out =new OutputStreamWriter(System.out,"UTF-8");
<!--[if !supportLists]-->21.<!--[endif]-->svgGenerator.stream(out, useCSS);
我们还可以使用指定SVGGeneratorContext实例的构造函数来创建SVGGraphics2D。通过实现自己的SVGGeneratorContext实例可以实现更高级定制。
您将在下面找到几个可能的自定义示例。
在SVG中增加注释代码
DOMImplementation impl =
GenericDOMImplementation.getDOMImplementation();
String svgNS ="http://www.w3.org/2000/svg";
Document myFactory = impl.createDocument(svgNS,"svg",null);
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
ctx.setComment("Generated by FooApplication with Batik SVG Generator");
SVGGraphics2D g2d =new SVGGraphics2D(ctx,false);
文档中嵌入字体后就可以脱离系统的字体限制。
DOMImplementation impl =
GenericDOMImplementation.getDOMImplementation();
String svgNS ="http://www.w3.org/2000/svg";
Document myFactory = impl.createDocument(svgNS,"svg",null);
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
ctx.setEmbeddedFontsOn(true);
SVGGraphics2D g2d =new SVGGraphics2D(ctx,true);
Every time you call one of the drawImage methods provided by the Graphics2D interface, a default representation of your image is created in a l
每次调用Graphics2D接口提供的drawImage方法时,你的图像的一个默认表示就会在一个位置被创建并放入一个默认文件中。例如,默认情况下,创建base64编码并嵌入SVG文件。另外,还可以选择将图像以SVG规范存为JPEG或PNG。可以通过显式地提供SVG生成器使用的图像处理程序来更改默认行为。同样,您将使用SVGGeneratorContext来实现这一点。在下面的例子中,所有的图片都被转换成PNG格式并写入到res/images目录中。.
DOMImplementation impl =
GenericDOMImplementation.getDOMImplementation();
String svgNS ="http://www.w3.org/2000/svg";
Document myFactory = impl.createDocument(svgNS,"svg",null);
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
GenericImageHandler ihandler =new ImageHandlerPNGEncoder("res/images",null);
ctx.setImageHandler(ihandler);
SVGGraphics2D g2d =new SVGGraphics2D(ctx,false);
对于每个drawImage调用,使用默认的图像处理程序会导致将图像数据的新副本写入SVG文件或外部文件。如果反复使用相同的图像,则可能导致SVG文件包含大量冗余数据。在初始生成SVG DOM树时,可以选择重用图像数据,但会有一些性能损失。为此,您使用一个专门的图像处理程序,如下所示.
DOMImplementation impl =
GenericDOMImplementation.getDOMImplementation();
String svgNS ="http://www.w3.org/2000/svg";
Document myFactory = impl.createDocument(svgNS,"svg",null);
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
// Reuse our embedded base64-encoded image data.
GenericImageHandler ihandler =new CachedImageHandlerBase64Encoder();
ctx.setGenericImageHandler(ihandler);
SVGGraphics2D g2d =new SVGGraphics2D(ctx,false);
有了缓存图像处理程序,甚至可以跨几个不同的SVG文档重用图像数据的相同副本。只需保留对图像处理程序的引用,并将其传递给用于生成SVG DOM树的SVGGraphics2D实例。下面的简化示例展示了不同的SVG生成器如何创建不同的SVG树,有效地只存储一次通用图像。.
classMySVGGenerator{
// The image handler will write all images files to "res/images".
privatestatic ImageHandler ihandler =
newCachedImageHandlerPNGEncoder("res/images",null);
publicvoidgenerateSVG(JPanel myCanvas, OutputStream outStream){
DOMImplementation domImpl =
GenericDOMImplementation.getDOMImplementation();
Document myFactory = domImpl.createDocument(svgNS,"svg",null);
SVGGeneratorContext ctx =
SVGGeneratorContext.createDefault(myFactory);
ctx.setGenericImageHandler(ihandler);
SVGGraphics2D svgGenerator =new SVGGraphics2D(ctx,false);
// Create the SVG DOM tree.
myCanvas.paintComponent(svgGenerator);
Writer out =new OutputStreamWriter(outStream,"UTF-8");
svgGenerator.stream(out,true);
}
}
您在样式方面的需求可能与所提供的两个选项(XML表示属性或CSS内联样式表)不同。例如,您可能希望将CSS属性放在SVG样式元素节中,并通过class属性引用它们。在这种情况下,您需要定义一个新的StyleHandler,如下所示。
publicclassStyleSheetStyleHandlerimplements StyleHandler {
// The CDATA section that holds the CSS stylesheet.
private CDATASection styleSheet;
// Build the handler with a reference to the stylesheet section.
publicStyleSheetStyleHandler(CDATASection styleSheet){
this.styleSheet= styleSheet;
}
publicvoidsetStyle(Element element, Map styleMap,
SVGGeneratorContext generatorContext){
Iterator iter = styleMap.keySet().iterator();
// Create a new class in the style sheet.
String id = generatorContext.getIDGenerator().generateID("C");
styleSheet.appendData("."+ id +" {");
// Append each key/value pair.
while(iter.hasNext()){
String key =(String) iter.next();
String value =(String) styleMap.get(key);
styleSheet.appendData(key +":"+ value +";");
}
styleSheet.appendData("}\n");
// Reference the stylesheet class on the element to be styled.
element.setAttributeNS(null,"class", id);
}
}
让后通过 SVGGraphics2D 配置 SVGGeneratorContext.
// Configure the SVGGraphics2D for a given Document myFactory.
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
CDATASection styleSheet = myFactory.createCDATASection("");
ctx.setStyleHandler(new StyleSheetStyleHandler(styleSheet));
SVGGraphics2D g2d =new SVGGraphics2D(ctx,false);
// Use the g2d to draw (e.g., component.paint(g2d)).
// Add a stylesheet to the definition section.
SVGSVGElement root =(SVGSVGElement) g2d.getRoot();
Element defs = root.getElementById(SVGSyntax.ID_PREFIX_GENERIC_DEFS);
Element style = myFactory.createElementNS
(SVGSyntax.SVG_NAMESPACE_URI, SVGSyntax.SVG_STYLE_TAG);
style.setAttributeNS(null, SVGSyntax.SVG_TYPE_ATTRIBUTE,"text/css");
style.appendChild(styleSheet);
defs.appendChild(style);
// Dump the root content to a given Writer myWriter.
g2d.stream(root, myWriter);
SVGGraphics2D能够为一般的Java 2D对象生成SVG元素,但是有时您也有自己的类,比如Java 2D Paint接口的实现。在这种情况下,您将需要编写一个ExtensionHandler,并将其设置在SVGGeneratorContext上。
在下面的示例中,我们定义了一个ExtensionHandler的初稿,它允许转换名为LinearGradientPaint的Paint接口的batik实现。
.
classMyExtensionHandlerextends DefaultExtensionHandler {
public SVGPaintDescriptor handlePaint(Paint paint,
SVGGeneratorContext generatorCtx){
if(paint instanceof LinearGradientPaint){
LinearGradientPaint gradient =(LinearGradientPaint) paint;
// Create a new SVG 'linearGradient' element to represent the
// LinearGradientPaint being used.
String id = generatorCtx.getIDGenerator().generateID("gradient");
Document doc = generatorCtx.getDOMFactory();
Element grad = doc.createElementNS
(SVGSyntax.SVG_NAMESPACE_URI,
SVGSyntax.SVG_LINEAR_GRADIENT_TAG);
// Set the relevant attributes on the 'linearGradient' element.
grad.setAttributeNS(null, SVGSyntax.SVG_ID_ATTRIBUTE, id);
grad.setAttributeNS(null, SVGSyntax.SVG_GRADIENT_UNITS_ATTRIBUTE,
SVGSyntax.SVG_USER_SPACE_ON_USE_VALUE);
Point2D pt = gradient.getStartPoint();
grad.setAttributeNS(null,"x1", pt.getX());
grad.setAttributeNS(null,"y1", pt.getY());
pt = gradient.getEndPoint();
grad.setAttributeNS(null,"x2", pt.getX());
grad.setAttributeNS(null,"y2", pt.getY());
switch(gradient.getCycleMethod()){
case MultipleGradientPaint.REFLECT:
grad.setAttributeNS
(null, SVGSyntax.SVG_SPREAD_METHOD_ATTRIBUTE,
SVGSyntax.SVG_REFLECT_VALUE);
break;
case MultipleGradientPaint.REPEAT:
grad.setAttributeNS
(null, SVGSyntax.SVG_SPREAD_METHOD_ATTRIBUTE,
SVGSyntax.SVG_REPEAT_VALUE);
break;
// 'pad' is the default...
}
// Here we should write the transform of the gradient
// in the transform attribute...
// Here we should write the stops of the gradients as
// children elements...
returnnewSVGPaintDescriptor
("url(#"+ ref +")", SVGSyntax.SVG_OPAQUE_VALUE, grad);
}else{
// Let the default mechanism do its job.
returnnull;
}
}
}
然后在 setExtensionHandler 中指定SVGGeneratorContext .
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
ctx.setExtensionHandler(new MyExtensionHandler());
SVGGraphics2D g2d =new SVGGraphics2D(ctx,false);
.
importjava.awt.*;
importjava.awt.geom.*;
importjavax.swing.*;
importorg.apache.batik.swing.*;
importorg.apache.batik.svggen.*;
importorg.apache.batik.dom.svg.SVGDOMImplementation;
importorg.w3c.dom.*;
importorg.w3c.dom.svg.*;
publicclassViewGeneratedSVGDemo{
publicstaticvoidmain(String[] args){
// Create an SVG document.
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
SVGDocument doc =(SVGDocument) impl.createDocument(svgNS,"svg",null);
// Create a converter for this document.
SVGGraphics2D g =new SVGGraphics2D(doc);
// Do some drawing.
Shape circle =new Ellipse2D.Double(0,0,50,50);
g.setPaint(Color.red);
g.fill(circle);
g.translate(60,0);
g.setPaint(Color.green);
g.fill(circle);
g.translate(60,0);
g.setPaint(Color.blue);
g.fill(circle);
g.setSVGCanvasSize(new Dimension(180,50));
// Populate the document root with the generated SVG content.
Element root = doc.getDocumentElement();
g.getRoot(root);
// Display the document.
JSVGCanvas canvas =new JSVGCanvas();
JFrame f =new JFrame();
f.getContentPane().add(canvas);
canvas.setSVGDocument(doc);
f.pack();
f.setVisible(true);
}
}
相关推荐
使用 Batik 生成 SVG 图形非常简单,只需要创建一个 `SVGGraphics2D` 对象,并将其添加到图形中即可。 ```java import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen....
3. **SAX SVG生成器**: 从SAX事件流生成SVG文档。 4. **Transcoder API**: 支持多种输入和输出格式的转换,如PDF、GIF、PNG等。 5. **Font Converter**: 用于将TrueType字体转换为SVG字体,以便在SVG环境中使用。 *...
1. **SVG解析和生成**:Batik提供了一个SVG解析器,能够读取SVG文件并将其转化为Java对象模型。同时,它也支持将这个对象模型重新渲染回SVG文件,实现了SVG的读写能力。 2. **SVG渲染引擎**: Batik的SVG渲染引擎...
4. **SVG生成器(SVG Generator)**: Batik可以将非SVG图形(如Swing组件或Java2D绘制)转换为SVG,这对于创建跨平台的图形输出非常有用。 5. **SVG字体**: Batik包含了对SVG字体的支持,允许在SVG文档中使用...
4. **SVG生成器**: Batik也提供了生成SVG文档的功能,允许程序动态创建SVG图形,这对于动态数据可视化和Web应用尤其有用。 5. **Rasterizer工具**: Batik的Rasterizer工具能够将SVG文件批量转换为位图图像,这在...
通过Batik,你可以在JAVA可以使用的地方操作SVG文档,您还可以在你的应用程序使用Batik模块来生成 , 处理和转码SVG图像。Batik很容易让基于Java的应用程序或小程序来处理SVG内容。 例如,使用Batik的SVG的发生器模块...
Batik是一个完整的SVG工具集,包括解析器、DOM实现、渲染引擎、CSS样式处理器、Rasterizer(用于将SVG转换为位图格式如JPEG或PNG)以及一系列的命令行工具。 Batik的主要优势在于它提供了SVG的完整生命周期支持,从...
例如,如果你需要从SVG生成PDF,你可能需要使用FOP、pdf-transcoder.jar和 Batik-all-1.6.jar。而xerces-1.2.3.jar和XML API的jar文件则确保了XML文档的有效解析。 总结来说,这些jar包构成了一个强大的SVG处理工具...
在Java中,我们可以使用DOM或SAX解析器来处理SVG文档,或者使用如Batik这样的库来生成和操作SVG。 Batik是一个开源的Java库,它可以解析、转换、渲染SVG图形,非常适合用于动态生成SVG内容。首先,我们需要创建一个...
Batik是Apache软件基金会的一个项目,提供了一个完整的SVG生态系统,包括解析、渲染、转换和生成SVG文档的工具。在SVGEditor中,GLIPS引擎负责解析SVG文件,将它们转化为可交互的图形对象,并实现编辑操作。 3. **...
在“batik.jar 与设计模式”的主题中,我们将深入探讨如何利用Apache Batik库,一个用于处理SVG(Scalable Vector Graphics)的Java工具包,以及在项目中应用设计模式来实现网页上的可缩放图表和图标交互。...
EchoSVG是Apache Batik的分支,Apache Batik是基于Java的工具箱,用于应用程序,这些应用程序以可缩放矢量图形(SVG)格式处理图像,以用于各种目的,例如查看,生成或操作。 由于使用了CSS4J样式解析器,因此支持...
3. **SVG生成器**:可以从内部数据结构重新生成SVG源代码。 4. **DOM实现**:提供了一个符合W3C SVG DOM规范的实现,使得开发者可以通过编程方式操作SVG元素。 5. **Transcoder API**:支持将SVG转换为其他格式,...
6. `batik-svggen.jar`:SVG生成器,能够将Java2D图形转化为SVG格式。 7. `batik-swing.jar`:提供了在Swing应用程序中显示和操作SVG的类。 8. `batik-dom.jar`:提供了对XML DOM接口的支持,包括SVG DOM。 9. `...
1. 解析SVG文件:首先,SVG-PDF-Exporter读取SVG文件,并使用Batik的SVG解析器将其转换为内部的SVG DOM(Document Object Model)表示。 2. 渲染SVG:然后,内部的SVG DOM被传递给渲染引擎,该引擎根据DOM内容生成...
【Java在SVG交互中的应用】虽然描述中没有直接提到Java,但通常Java可以用于服务器端处理SVG,比如生成SVG内容,或者通过Java的Batik库解析和操作SVG。Batik是Apache项目的一个开源工具,它提供了一整套处理SVG的API...
3. Batik库:Batik是Apache基金会的一个开源项目,它提供了一套完整的SVG工具集,包括SVG解析器、渲染器、转换器等。在本场景中, Batik可能用于将地理信息数据转换为SVG格式,或者将SVG地图进行动态操作,例如添加...
它在源SVG标记中获取根元素的内容(通常,根元素将为 ),将其包装到标记中并返回生成的标记。 使用加载器参数可以使用另一个标签代替 。 应用于源SVG文件中根元素的属性将保留并应用于目标标签。 如果源SVG图像包含...
《基于Spring和Java的2D字符生成器技术详解》 在现代数字艺术和游戏开发领域,2D字符生成器扮演着重要角色,它们能够自动生成各种各样的虚拟人物形象,节省设计人员的时间并提高创作效率。本文将深入探讨一个利用...