新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论SVG, GML, X3D, VRML, VML, XAML, AVALON, Batik等基于XML的图形技术,以及有关GIS的应用。
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - 高级XML应用『 SVG/GML/VRML/X3D/XAML 』 → Batik 入门(四)[转帖] 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 6822 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: Batik 入门(四)[转帖] 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     supremeweb 帅哥哟,离线,有人找我吗?
      
      
      等级:大三(要不要学学XML呢?)
      文章:87
      积分:661
      门派:XML.ORG.CN
      注册:2006/6/13

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给supremeweb发送一个短消息 把supremeweb加入好友 查看supremeweb的个人资料 搜索supremeweb在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看supremeweb的博客楼主
    发贴心情 Batik 入门(四)[转帖]

    SVG 生成器: SVGGraphics2D

    在java平台中所有的绘图,都通过Graphics2D抽象类,这个类提供象drawRect,fillRect,drawString这样的方法。对于每个类型的输出这个抽象类都有指定的执行,比如屏幕或者打印机。SVGGraphics2D是这个接口的一个新的执行生成SVG内容,以用来替代画到屏幕或者打印机上。

    SVGGraphics2D 拥有以下特性:
    1.它允许应用程序输出图形到SVG格式
    2.它输出图形到svg格式,不需要修改任何图形代码
    3。它提供用户使用DOMApi操作生成文档的能力



    此主题相关图片如下:
    按此在新窗口浏览图片

    以上图形显示生成器是怎样用DOMAPI工作的。W3C已经定义了一个API用来显示带有java对象的XML内容。这个API允许程序员在内存中操作,创建或者修改XML内容。DOMAPI包含象document,Element,Attr的接口,这些接口等价于java语言中的XML documents, elements 和attributes。

    生成器管理一个DOM对象树用来显示相应于SVGGraphics2D实例的svg内容。换句话说,每次一个程序调用一个绘图方法,比如fillRect,在一个SVGGraphics2D实例中,一个新的DOM对象,描绘等价SVG,被添加到DOM树中。举个例子,一个矩形元素将在fillrect方法调用后被添加。

    程序员使用这个生成器,可以存储DOM树到更深层的操作,或者可以直接写内容到一个输出流中,就象我们下面选项中看到的那样。

    怎样使用SVGGraphics2D

    从上面部分的描述我们可以看到为了使用一个SVGGraphics2D实例来构建SVG内容,一个文档类实例是必须的。DOM树是svg文档的内存内表现,它可以被用户使用DOMAPI深入操作,或者通过一个Write对象,流输出。下面的例子证明怎么从java图形中怎么生成SVG内容

    import java.awt.Rectangle;
    import java.awt.Graphics2D;
    import java.awt.Color;
    import java.io.Writer;
    import java.io.OutputStreamWriter;
    import java.io.IOException;

    import org.apache.batik.svggen.SVGGraphics2D;
    import org.apache.batik.dom.GenericDOMImplementation;

    import org.w3c.dom.Document;
    import org.w3c.dom.DOMImplementation;

    public class TestSVGGen {

        public void paint(Graphics2D g2d) {
            g2d.setPaint(Color.red);
            g2d.fill(new Rectangle(10, 10, 100, 100));
        }

        public static void main(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实例中生成SVG内容包括三个步骤:
    1.创建一个org.w3c.dom.Document实例,以便生成器用来构建它的XML内容,并且使用Document实例创建一个SVG生成器
    // 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);
    2.调用SVG生成器上的描绘代码。在我们的例子中,我们调用了TestSVGGen的paint方法
    // Ask the test to render into the SVG Graphics2D implementation.
            TestSVGGen test = new TestSVGGen();
            test.paint(svgGenerator);
    3.流输出svg内容。svg生成器可以流输出它的内容到任意的java.io.Writer中。在我们的例子中,我们流输出内容到标准的输出流中
            // 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);
    svg有两种方式来指定风格属性,比如填充颜色,显示属性或者CSS类型属性。useCss 参数允许用户使用这个属性

    svg生成器定制

    在前面的段落中,我们已经看到SVG生成程序可以被定制来输出svg类型属性作为显示属性,或者css在线属性。在这个部分里我们将讨论一些高级定制的例子。
    为了替代创建SVGGraphics2D只使用象创建SVG元素的工厂那样的document,我们可以使用一个SVGGeneratorContext 实例的构造器。通过提供你拥有的SVGGeneratorContext 实例,你将可以进行高级定制。你将发现如下的例子可以被定制。

    1.在生成的SVG文件中存在你自己的注释
    下面我们开始简单可行的例子。如果你在自己的java应用程序中结合Batik SVG生成器,你将希望在XML代码中生成专门的注释。
    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);

    2.在生成的SVG文件中使用嵌入式svg字体
    要有一个不使用系统字体来显示的独立的svg文件,你可以自己在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);

    3.定制图片存储路径
    每次你调用一个通过SVGGraphics2D接口提供的drawImage方法时,默认图片绘制被创建并且放到一个默认文件中。举个实例,一个base64编码被创建,并且通过默认嵌入到svg文件中去。作为选择,你可以选择将图片写到事先定义好的文件夹中的一个单独的文件里。文件格式是svg规范要求的两种光栅格式图片:jpeg,png
    你可以改变默认行为,通过在svg生成器中提供明确的提供图片句柄来使用。下面例子中所有图片将转换为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文件中包含许多冗余信息。在初始化SVGDOm树的时候将会有微小的性能损失,你可以选择将图片重复使用。为了这个原因你要使用一个指定的图片处理器,如下:
    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树使用的SVGGraphics实例中。下面简单的一个例子用来论证不同的SVG树通过单独的SVG生成器被创建,以便有效的存储任何通用图片。

    class MySVGGenerator {

        // The image handler will write all images files to "res/images".
        private static ImageHandler ihandler =
            new CachedImageHandlerPNGEncoder("res/images", null);

        public void generateSVG(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 presentation attributes or CSS inline stylesheets)。举个例子,你可以希望将CSS属性方知道一个SVG风格的元素不分离,并且通过类属性提及到他们。那么你将需要定制一个如下所示的新的stylehandler

    public class StyleSheetStyleHandler implements StyleHandler {

        // The CDATA section that holds the CSS stylesheet.
        private CDATASection styleSheet;

        // Build the handler with a reference to the stylesheet section.
        public StyleSheetStyleHandler(CDATASection styleSheet) {
            this.styleSheet = styleSheet;
        }

        public void setStyle(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);
        }
    }

    然后你可以创建并且使用一个有正确配置的SVGGeneratorContext的一个SVGGraphics

    2D

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

    扩展paint对象到SVG元素转换

    SVGGraphics2D可以为通用的java 2d对象生成SVG元素,但是有时候你可以用你自己的类,比如java 2D Paint的执行接口。因为这个原因你需要写一个你将要设置在你的SVGGeneratorContext中的ExtensionHandler。
    在下边的例子中,我们定义ExtensionHandler的一个草图,这个草图允许转换一个Paint接口的Batik执行,名称叫LinearGradientPaint。
    class MyExtensionHandler extends 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...

                return new SVGPaintDescriptor
                    ("url(#" + ref + ")", SVGSyntax.SVG_OPAQUE_VALUE, grad);
            } else {
                // Let the default mechanism do its job.
                return null;
            }
        }
    }
    然后你需要在SVGGeneratorContext上,通过使用setExtensionHandler方法设定它。

    SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
    ctx.setExtensionHandler(new MyExtensionHandler());
    SVGGraphics2D g2d = new SVGGraphics2D(ctx, false);

    怎样查看生成的SVG文档

    下面的代码详细描述怎么查看利用SVGGraphics2D对象生成的svg内容
    import java.awt.*;
    import java.awt.geom.*;

    import javax.swing.*;

    import org.apache.batik.swing.*;
    import org.apache.batik.svggen.*;
    import org.apache.batik.dom.svg.SVGDOMImplementation;

    import org.w3c.dom.*;
    import org.w3c.dom.svg.*;

    public class ViewGeneratedSVGDemo {

        public static void main(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);
        }
    }


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/4/2 13:48:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/12/23 7:46:58

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    125.000ms