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

    >> 本版讨论SVG, GML, X3D, VRML, VML, XAML, AVALON, Batik等基于XML的图形技术,以及有关GIS的应用。
    [返回] 计算机科学论坛XML.ORG.CN讨论区 - 高级XML应用『 SVG/GML/VRML/X3D/XAML 』 → Server Side SVG 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3644 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: Server Side SVG 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 Server Side SVG

    If you've been using SVG or reading XML.com, you probably know about the Adobe SVG Viewer, and you may have heard of the Apache Batik project. Although Batik is most widely known for its SVG viewer component, it's more than that. Batik, according to its web site, is a “Java technology-based toolkit for applications that want to use images in the Scalable Vector Graphics (SVG) format for various purposes, such as viewing, generation or manipulation.”
    The Batik viewer application uses the JSVGCanvas component, which is a Java class that accepts SVG as input and displays it on screen. In this article, we'll use two of the other Batik components, SVGGraphics2D, and the Batik transcoders. The SVGGraphics2D class is the inverse of JSVGCanvas; you draw into an SVGGraphics2D environment using the standard Java two-dimensional graphics methods, and the result is an SVG document. The transcoders take an SVG document as input and produce either JPG or PNG as output.
    The context in which we'll use these tools is a servlet that generates geometric art in the style of Piet Mondrian. If the client supports SVG, the servlet will return an SVG document. Otherwise, it will return a JPEG or PNG image, depending upon client support for those image formats.

          Print
       Email article link
       Discuss
       Add to Project
     

    Server Side SVG
    by J. David Eisenberg
    February 27, 2002

    <script></script>  
    If you've been using SVG or reading XML.com, you probably know about the Adobe SVG Viewer, and you may have heard of the Apache Batik project. Although Batik is most widely known for its SVG viewer component, it's more than that. Batik, according to its web site, is a “Java technology-based toolkit for applications that want to use images in the Scalable Vector Graphics (SVG) format for various purposes, such as viewing, generation or manipulation.”
    The Batik viewer application uses the JSVGCanvas component, which is a Java class that accepts SVG as input and displays it on screen. In this article, we'll use two of the other Batik components, SVGGraphics2D, and the Batik transcoders. The SVGGraphics2D class is the inverse of JSVGCanvas; you draw into an SVGGraphics2D environment using the standard Java two-dimensional graphics methods, and the result is an SVG document. The transcoders take an SVG document as input and produce either JPG or PNG as output.
    The context in which we'll use these tools is a servlet that generates geometric art in the style of Piet Mondrian. If the client supports SVG, the servlet will return an SVG document. Otherwise, it will return a JPEG or PNG image, depending upon client support for those image formats.
    The Client Side
    The web page that we show users will let them choose the orientation and color scheme of their painting. See the screenshot below for an example of how this might look.

    Here's the HTML:
    <html>
    <head>
    <title>Art-O-Matic</title>
    </head>

    <body>
    <h2>Art-O-Matic</h2>
    <p>
    Yes, you too can become a famous artist! With a few simple clicks
    of the mouse, you can generate geometric art in the style of
    Piet Mondrian.
    </p>

    <form id="artForm"
        action="http://jde:8080/artmaker/servlet/ArtMaker">
    <p>
    What kind of picture would you like?
    <br />
    <input type="radio" name="picType" value="landscape"
        checked="checked" /> Landscape
    <input type="radio" name="picType" value="portrait" /> Portrait
    <input type="radio" name="picType" value="square" /> Square
    </p>

    <p>
    Which color scheme would you like?
    <br />
    <input type="radio" name="scheme" value="bright"
        checked="checked" /> Vivid colors
    <input type="radio" name="scheme" value="pastel" /> Soft pastel
    </p>
    </body>
    </html>
    Determining whether the client has SVG support or not must be handled on the client side. We'll add this script, taken from a Sun Microsystems technical note, to do this detection.
    <script type="text/javascript">
    <!-- <![CDATA[

    var hasSVGSupport = false;  // does client have SVG support?
    var useVBMethod = false;    // use VBScript or JavaScript?

    /*
        Internet Explorer returns 0 as the number of MIME types,
        so this code will not be executed by it. This is our indication
        to use VBScript to detect SVG support.
    */
    if (navigator.mimeTypes != null
        && navigator.mimeTypes.length > 0)
    {
        if (navigator.mimeTypes["image/svg+xml"] != null)
        {
            hasSVGSupport = true;
        }
    }
    else
    {
        useVBMethod = true;
    }
    // ]]> -->
    </script>

    <!--
        Visual Basic Script to detect support of Adobe SVG plugin.
        This code is not run on browsers which report they have MIME types,
        and it is also not run by browsers which do not have VBScript support.
    -->
    <script type="text/vbscript">
    On Error Resume Next
    If useVBMethod = true Then
        hasSVGSupport = IsObject(CreateObject("Adobe.SVGCtl"))
    End If
    </script>
    In order to have the web page send this information back to the server, we'll have to change the <form> tag and add a hidden field to our form:
    <form id="artForm"
        action="http://jde:8080/artmaker/servlet/ArtMaker"
        onsubmit="return setSVGStatus();">

    <input type="hidden" name="imgType" value="jpg" />
    Which requires an additional script to set the hidden field before we send the data to the server:
    <script type="text/javascript">
    <!-- <![CDATA[
    function setSVGStatus()
    {
        if (hasSVGSupport)
        {
            var theForm = document.getElementById("artForm");
            theForm.imgType.value = "svg";
        }
        return true;
    }
    // ]]> -->
    </script>


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/1/19 8:33:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    The Server Side
    Questions about this article? Share them with the author and other readers in our forum.
    Post your comments
    First, we need Java code to draw the actual painting into a Graphics2D context. You may see the Artist.java source. There's nothing particularly special about it; it's just a few draw and fill calls in a recursive function. The only thing to note is the constructor, which requires a width, height, and palette (which will be BRIGHT or PASTEL):
    public Artist( int width, int height, int colorType );
    Now, on to the servlet. We'll do all the work in the doPost method. We start by sending out header information to keep the results from being cached:
    public class ArtMaker extends HttpServlet {

        public void doPost(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException
        {

            Artist mondrian = null;
        
            try
            {
                response.setHeader("Cache-Control",
                    "no-cache, no-store, must-revalidate");
                response.setHeader("Cache-Control",
                    "post-check=0, pre-check=0");
                String agent =
                    request.getHeader("User-Agent").toLowerCase();
            
                /* netscape chokes on Pragma no-cache so only
                    send it to explorer */

                if (agent.indexOf("explorer") > -1){
                  response.setHeader("Pragma", "no-cache");
                }
                response.setHeader("Expires",
                    "Thu, 01 Dec 1994 16:00:00 GMT");
    We then grab the parameters, use them to set some local variables, and create an appropriate Artist.
    String picType = request.getParameter( "picType" );
    String colorScheme = request.getParameter( "scheme" );         
    String imgType = request.getParameter( "imgType" );

    Artist mondrian = null;

    int width;
    int height;
    int palette;

    if (picType.equals("landscape"))
    {
        width = 400;
        height = 300;
    }
    else if (picType.equals("portrait"))
    {
        width = 200;
        height = 300;
    }
    else
    {
        width = 250;
        height = 250;
    }

    palette = (colorScheme.equals("bright")) ?
        Artist.BRIGHT : Artist.PASTEL;

    mondrian = new Artist( width, height, palette );
    Once this is set, we need to create an SVG document and an SVG graphics environment. Since every parser implementation has its own way of storing the objects, you must ask the SVGDOMImplementation class to give you the details. Once you know the details, you can ask the implementation to create a document with the appropriate namespace, which is in svgNS. The third argument to createDocument is a reference to a list of entities defined for the document. There aren't any in this case, so we set the third argument to null.
    DOMImplementation domImpl =
        SVGDOMImplementation.getDOMImplementation();
                
    String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
    Document document =
        domImpl.createDocument(svgNS, "svg", null);
    We then construct the SVGGraphics2D object and associate it with the document that it will create. We set the graphic environment's dimensions to the desired height and width with ten extra pixels for padding around the edges.
    SVGGraphics2D svgGraphicsEnvironment = new SVGGraphics2D(document);
    svgGraphicsEnvironment.setSVGCanvasSize(
        new Dimension( width + 10, height + 10 )
    );
    Everything is now set up. We just tell our artist to paint into that graphic environment, and the corresponding SVG document will be built up automatically.
    mondrian.paint( svgGraphicsEnvironment );
    Now the document is in memory, but we will need it in text form to send back to the client. We accomplish this by streaming the document to a ByteArrayOutputStream, whose initial size is 8192 bytes, which should be enough for most normal paintings that this code will generate. The second parameter to stream is set to true, indicating that the output should use CSS styles instead of style attributes.
    ByteArrayOutputStream baos = new ByteArrayOutputStream( 8192 );
    Writer svgOutput = new OutputStreamWriter( baos, "UTF-8" );
    svgGraphicsEnvironment.stream( svgOutput, true );
    We now determine whether we need to send back an SVG, JPEG, or PNG image. The client has told us whether we can use SVG or not. The information about PNG support is in the HTTP request's Accept header. In each case, we take the SVG output byte array, convert it to a string, and pass it on to the appropriate emit function.
    if (imgType.equals("svg"))  
    {
        emitSVG( request, response, baos.toString() );
    }
    else
    {
        if (request.getHeader("Accept").indexOf("png") >= 0)
        {
            emitPNG( request, response, baos.toString() );
        }
        else
        {
            emitJPG( request, response, baos.toString() );
        }
    }
    The remainder of the doPost method is the error trapping; in case anything fails, we send back an HTML page with an error message.
    catch (Exception e)
    {
        PrintWriter out = response.getWriter();
        response.setContentType("text/html");
        out.println("<?xml version="1.0" encoding="utf-8"?>");
        out.println("<!DOCTYPE");
        out.println("html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"");
        out.println("\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
        out.println("<html><head><title>Error</title></head>");
        out.println("<body>");
        out.println("<p>Unable to create painting.</p>");
        out.println("<pre>");
        e.printStackTrace(out);
        out.println("</pre>");
        out.println("</body></html>");
    }
    This leaves the three emit... methods. emitSVG is trivial; we just send the string back to the client with an appropriate MIME type:
    public void emitSVG( HttpServletRequest request,
        HttpServletResponse response,
        String svgString )
    {
        response.setContentType( "image/svg+xml" );
        try {

            response.getWriter().write( svgString );
            response.getWriter().flush();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/1/19 8:34:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客3
    发贴心情 
    Transcoding
    To send back a JPEG or PNG file, we have to use Batik's transcoder. Input to the transcoder can be a document, a stream, or a Reader; output can be a URI, stream, or Writer. For the JPEG transcoder, you may set the output quality by calling the addTranscodingHint method. Since we're sending a series of bytes back to the client rather than a string, we're sending output to response.getOutputStream() rather than response.getWriter().
    public void emitJPG( HttpServletRequest request,
        HttpServletResponse response, String svgString )
    {
        response.setContentType("image/jpeg");

        JPEGTranscoder t = new JPEGTranscoder();
        t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
                             new Float(.8));

        TranscoderInput input =
            new TranscoderInput( new StringReader(svgString) );
        try {
            TranscoderOutput output =
                new TranscoderOutput(response.getOutputStream());
            t.transcode(input, output);
            response.getOutputStream().close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    Similar code sends PNG output; you may give it an additional hint with KEY_FORCE_TRANSPARENT_WHITE if you want fully transparent pixels to appear as white. This is good for older browsers that don't support PNG transparency completely.
    public void emitPNG ( HttpServletRequest request,
        HttpServletResponse response, String svgString )
    {
        response.setContentType("image/png");

        PNGTranscoder t = new PNGTranscoder();

        TranscoderInput input =
            new TranscoderInput( new StringReader(svgString) );
        try {
            TranscoderOutput output =
                new TranscoderOutput(response.getOutputStream());
            t.transcode(input, output);
            response.getOutputStream().close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    You may examine the entire servlet as one file. If you install Artist and Artmaker in a suitable servlet container such as Jakarta Tomcat, you too can produce art like this, which I've shrunk to half size to take up less screen space.

    Summary
    Other Batik tools which we haven't covered here let you convert TrueType fonts to SVG and extend SVG to include custom tags. If you want a powerful, cross-platform toolkit for building applications that let you view, construct, and convert SVG documents, Batik is the answer.

    Questions about this article? Share them with the author and other readers in our forum.
    (* You must be a member of XML.com to use this feature.)
    Comment on this Article

    Titles Only  Titles Only  Newest First
    · Altering SVG Document
    2002-03-19 05:34:24 Phillip Larsen [Reply]

    Thankyou for a great article on Server Side SVG.

    I have one question however. What if you wanted to alter any nodes in the SVG Document created when using SVGGraphics2D as a graphical context in Java2D ? What I am trying to say is, what if, when you have returned from creating the wanted graphics, you for instance would like to add a link to a square in the SVG image you have created. How would you go about doing that ?

    Regards
    Phillip Larsen
    · trouble compiling ArtMaker.java
    2002-03-18 12:42:10 Bill Carter [Reply]

    Hi,

    I am trying to replicate this example and am having trouble compiling ArtMaker.java into a servlet.

    my command line looks like this:

    javac -sourcepath c:\xml-batik\sources -classpath c:\Progra~1\Allaire\JRun\lib\ext\servlet.jar;c:\Progra~1\Allaire\JRun\lib\ext\tools.jar;c:\Progra~1\Allaire\JRun\lib\ext\parser.jar;c:\xml-batik\sources;c:\Progra~1\Allaire\JRun\servers\default\default-app\WEB-INF\classes

    ArtMaker.java

    javac:\xml-batik\sources\org\apache\batik\transcoder\image\ImageTranscoder.java:413:
    Variable hints in class org.apache.batik.transcoder.TranscoderSupport not accessible from inner class org.apache.batik.transcoder.image.ImageTranscoder. ImageTranscoderUserAgent.return (String)hints.get(KEY_MEDIA);
    ^
    1 error

    any help would be greatly appreciated.

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

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

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

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