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

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

  }

}

 

分享到:
评论

相关推荐

    使用batik转换svg文件

    自己通过实际项目总结出的batik的基本使用方法,可以使用里面的工具类来操作svg文件。网络资源很少的哦,还不快下载。

    Batik详细教程

    Batik 是为想使用 svg 格式图片来实现各种功能的应用程序和 Applet 提供的一个基于 java 的工具包。 工程创建的目的是为开发者提供一系列可以结合或单独使用来支持特殊的 svg 解决方案的核心模块。模块主要有 ...

    Eclipse 的svg插件batik-plugin

    你也可以使用各种Batik模块来在你的应用程序和Applet中来生成,操作和转换你的svg图像。 batik使通过java处理SVG内容变的简单。举个例子,通过使用batik的SVGGernerate模块,java应用程序和Applet可以非常简单的使...

    batik将svg转成图片,并用itext将图片写在pdf里

    NULL 博文链接:https://narutolby.iteye.com/blog/1605814

    batik-svg-dom-1.5.jar

    官方版本,亲测可用

    batik-ttf2svg-1.7.jar

    官方版本,亲测可用

    batik-svg-dom-1.6-1.jar

    官方版本,亲测可用

    batik-svg-dom-1.7.jar

    java运行依赖jar包

    基于Batik及SVG的监控画面的图模库一体化平台设计

    基于Batik及SVG的监控画面的图模库一体化平台设计

    Batik 1.7 API CHM格式

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

    java解析svg文件

    基于Batik的对svg文件进行解析显示

    svg_jar Batik

    java解析、生成svg图所用到的jar包。一个基于Java的应用程序或小应用的工具集,意图将SVG格式用于多种目的,如查看,主控或操纵

    javaHighcharts 导出图表的batik 等资源包

    javaHighcharts 导出图表引用的资源包 import org.apache.batik.transcoder.Transcoder; import org.apache.batik....import org.apache.fop.svg.PDFTranscoder; batik-all-1.6.jar fop.jar xerces-2.9.0.jar

    JAVA WMF 转换SVG,PNG

    WMF转PNG EMF转PNG 工具类,使用wmf2svg 来实现wmf转svg 用batik jar实现svg转png 这种转换 不存在图片丢失等问题!

    batik 2.7 jars

    batik-anim-1.7.jar batik-awt-util-1.7.jar batik-bridge-1.7.jar batik-codec-1.7.jar ...batik-svg-dom-1.7.jar batik-svggen-1.7.jar batik-transcoder-1.7.jar batik-util-1.7.jar batik-xml-1.7.jar

    batik-1.13.rar

    Batik 是为想使用 svg 格式图片来实现各种功能的应用程序和 Applet 提供的一个基于 java 的工具包。

    batik所有架包.rar

    batik-anim batik-awt-util batik-bridge batik batik-codec batik-css batik-dom batik-ext batik-extension batik-gui-util batik-gvt batik-parser batik-rasterizer batik-script batik-svg-dom batik-...

    batik-svg-dom.jar

    官方版本,亲测可用

    org.apache.batik包

    这里是batik包,用于生成svg格式的文件,支持javase1.4以上

    基于Batik及SVG的监控画面的 图模库一体化平台设计(转)

    NULL 博文链接:https://tw-wangzhengquan.iteye.com/blog/1322436

Global site tag (gtag.js) - Google Analytics