`
hjk685
  • 浏览: 101872 次
  • 来自: ...
社区版块
存档分类
最新评论

batik SVG生成器

 
阅读更多

SVG Generator: SVGGraphics2D

 

Java程序可以将图形绘制为SVG,然后在任何SVG查看器中查看,本文主要解释了BatikSVGGraphics2D(SVG生成器,)是如何实现这一点的。

The SVGGraphics2D class

On the Java platform, all rendering goes through the Graphics2D abstract class, which offers methods such as drawRectfillRect, 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抽象类实现,该类提供了drawRectfillRectdrawString等方法。对于每种输出类型(如屏幕或打印机),都由这个抽象类的专用实现。SVGGraphics2DGraphics2D接口的的新实现,它将绘制内容生成SVG内容,而不是绘制到屏幕或打印机上。

SVGGraphics2D 具有以下特点:

<!--[if !supportLists]-->·        <!--[endif]-->将图形导出为SVG格式

<!--[if !supportLists]-->·        <!--[endif]-->不需要修改任何代码直接输出为SVG文档

<!--[if !supportLists]-->·        <!--[endif]-->为用户提供使用 DOM API 操作SVG文档

W3C已经定义了一个用于用Java对象表示XML内容的DOM API 。允许程序员在内存中操作、创建和/或修改XML内容。DOM API包含DocumentElementAttr等接口,这些接口为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树进一步操作它,或者直接将内容写入输出流,如下一节所示。

How to use SVGGraphics2D

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);

SVG Generator 自定义

我们还可以使用指定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);

在生成的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.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规范存为JPEGPNG。可以通过显式地提供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);

  }

}

定义 SVG 样式

您在样式方面的需求可能与所提供的两个选项(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);

将绘图对象扩展为SVG 元素变换

SVGGraphics2D能够为一般的Java 2D对象生成SVG元素,但是有时您也有自己的类,比如Java 2D Paint接口的实现。在这种情况下,您将需要编写一个ExtensionHandler,并将其设置在SVGGeneratorContext上。

在下面的示例中,我们定义了一个ExtensionHandler的初稿,它允许转换名为LinearGradientPaintPaint接口的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);

如何查看生成的SVG文档

.

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);

  }

}

 

分享到:
评论

相关推荐

    纯Java动态生成SVG饼图与JFreeChart超强功能生成SVG图表

    使用 Batik 生成 SVG 图形非常简单,只需要创建一个 `SVGGraphics2D` 对象,并将其添加到图形中即可。 ```java import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen....

    svg_jar Batik

    3. **SAX SVG生成器**: 从SAX事件流生成SVG文档。 4. **Transcoder API**: 支持多种输入和输出格式的转换,如PDF、GIF、PNG等。 5. **Font Converter**: 用于将TrueType字体转换为SVG字体,以便在SVG环境中使用。 *...

    org.apache.batik包

    4. **SVG生成器(SVG Generator)**: Batik可以将非SVG图形(如Swing组件或Java2D绘制)转换为SVG,这对于创建跨平台的图形输出非常有用。 5. **SVG字体**: Batik包含了对SVG字体的支持,允许在SVG文档中使用...

    batik框架 jar包

    1. **SVG解析和生成**:Batik提供了一个SVG解析器,能够读取SVG文件并将其转化为Java对象模型。同时,它也支持将这个对象模型重新渲染回SVG文件,实现了SVG的读写能力。 2. **SVG渲染引擎**: Batik的SVG渲染引擎...

    batik源码(包含sample)

    4. **SVG生成器**: Batik也提供了生成SVG文档的功能,允许程序动态创建SVG图形,这对于动态数据可视化和Web应用尤其有用。 5. **Rasterizer工具**: Batik的Rasterizer工具能够将SVG文件批量转换为位图图像,这在...

    Batik 1.7 API CHM格式

    通过Batik,你可以在JAVA可以使用的地方操作SVG文档,您还可以在你的应用程序使用Batik模块来生成 , 处理和转码SVG图像。Batik很容易让基于Java的应用程序或小程序来处理SVG内容。 例如,使用Batik的SVG的发生器模块...

    基于Batik的java客户端程序

    Batik是一个完整的SVG工具集,包括解析器、DOM实现、渲染引擎、CSS样式处理器、Rasterizer(用于将SVG转换为位图格式如JPEG或PNG)以及一系列的命令行工具。 Batik的主要优势在于它提供了SVG的完整生命周期支持,从...

    batik的相关jar包

    例如,如果你需要从SVG生成PDF,你可能需要使用FOP、pdf-transcoder.jar和 Batik-all-1.6.jar。而xerces-1.2.3.jar和XML API的jar文件则确保了XML文档的有效解析。 总结来说,这些jar包构成了一个强大的SVG处理工具...

    使用svg动态生成12份圆

    在Java中,我们可以使用DOM或SAX解析器来处理SVG文档,或者使用如Batik这样的库来生成和操作SVG。 Batik是一个开源的Java库,它可以解析、转换、渲染SVG图形,非常适合用于动态生成SVG内容。首先,我们需要创建一个...

    SVGEditor1.3源代码

    Batik是Apache软件基金会的一个项目,提供了一个完整的SVG生态系统,包括解析、渲染、转换和生成SVG文档的工具。在SVGEditor中,GLIPS引擎负责解析SVG文件,将它们转化为可交互的图形对象,并实现编辑操作。 3. **...

    batik .jar 与设计模式

    在“batik.jar 与设计模式”的主题中,我们将深入探讨如何利用Apache Batik库,一个用于处理SVG(Scalable Vector Graphics)的Java工具包,以及在项目中应用设计模式来实现网页上的可缩放图表和图标交互。...

    echosvg:Java语言中的SVG实现,Apache Batik的分支,支持4级选择器

    EchoSVG是Apache Batik的分支,Apache Batik是基于Java的工具箱,用于应用程序,这些应用程序以可缩放矢量图形(SVG)格式处理图像,以用于各种目的,例如查看,生成或操作。 由于使用了CSS4J样式解析器,因此支持...

    batik-开源

    3. **SVG生成器**:可以从内部数据结构重新生成SVG源代码。 4. **DOM实现**:提供了一个符合W3C SVG DOM规范的实现,使得开发者可以通过编程方式操作SVG元素。 5. **Transcoder API**:支持将SVG转换为其他格式,...

    HighCharts导出的Servlet

    6. `batik-svggen.jar`:SVG生成器,能够将Java2D图形转化为SVG格式。 7. `batik-swing.jar`:提供了在Swing应用程序中显示和操作SVG的类。 8. `batik-dom.jar`:提供了对XML DOM接口的支持,包括SVG DOM。 9. `...

    svg-pdf-exporter:一个简单的 PDF 编辑器,用于创建带有文本和 svg 图像的 pdf 文件

    1. 解析SVG文件:首先,SVG-PDF-Exporter读取SVG文件,并使用Batik的SVG解析器将其转换为内部的SVG DOM(Document Object Model)表示。 2. 渲染SVG:然后,内部的SVG DOM被传递给渲染引擎,该引擎根据DOM内容生成...

    基于JavaScript及JAVA的SVG交互应用.pdf

    【Java在SVG交互中的应用】虽然描述中没有直接提到Java,但通常Java可以用于服务器端处理SVG,比如生成SVG内容,或者通过Java的Batik库解析和操作SVG。Batik是Apache项目的一个开源工具,它提供了一整套处理SVG的API...

    svg地图服务

    3. Batik库:Batik是Apache基金会的一个开源项目,它提供了一套完整的SVG工具集,包括SVG解析器、渲染器、转换器等。在本场景中, Batik可能用于将地理信息数据转换为SVG格式,或者将SVG地图进行动态操作,例如添加...

    svg-as-symbol-loader:一个Webpack加载器,它将源SVG文件的根元素的内容包装在其中元素并返回结果标记

    它在源SVG标记中获取根元素的内容(通常,根元素将为 ),将其包装到标记中并返回生成的标记。 使用加载器参数可以使用另一个标签代替 。 应用于源SVG文件中根元素的属性将保留并应用于目标标签。 如果源SVG图像包含...

    character-generator:以Spring和Java为后端构建2D字符生成器

    《基于Spring和Java的2D字符生成器技术详解》 在现代数字艺术和游戏开发领域,2D字符生成器扮演着重要角色,它们能够自动生成各种各样的虚拟人物形象,节省设计人员的时间并提高创作效率。本文将深入探讨一个利用...

Global site tag (gtag.js) - Google Analytics