<?xml version="1.0"?>

<!--

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

-->

<!-- ========================================================================= -->
<!-- author tkormann@apache.org                                                -->
<!-- version $Id: rasterizerTutorial.xml 327785 2005-10-23 12:38:58Z deweese $ -->      
<!-- ========================================================================= -->

<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
<document>
  <header>
    <title>Transcoder API</title>
  </header>

  <body>
    <p>
      The goal of the transcoder API (package
      <code>org.apache.batik.transcoder</code>) is to provide a generic
      API for transcoding an input to an output. First, this document
      explains the basic transcoder API that
      <a class="class" href="../javadoc/org/apache/batik/transcoder/Transcoder.html">Transcoder</a>,
      <a class="class" href="../javadoc/org/apache/batik/transcoder/TranscoderInput.html">TranscoderInput</a>
      and
      <a class="class" href="../javadoc/org/apache/batik/transcoder/TranscoderOutput.html">TranscoderOutput</a>
      define, and thus all transcoders have in common.  Next, it describes
      how to use the image transcoder API (package
      <code>org.apache.batik.transcoder.image</code>), which lets you
      rasterize an SVG document fragment to a raster image such as JPEG,
      PNG or TIFF.
    </p>
  
    <section id="transcoderAPI">
      <title>The transcoder API</title>
      <p>
        The <code>org.apache.batik.transcoder</code> package defines 5 major
        classes:
      </p>
      <dl>
        <dt>Transcoder</dt>
        <dd>
          <p>
            The
            <a class="class" href="../javadoc/org/apache/batik/transcoder/Transcoder.html">Transcoder</a>
            interface defines the interface that all transcoders implement. You can
            transcode a specific input using a specific output by invoking the
            <code>transcode</code> method. Although there is no assumption on the
            input and output format, a specific transcoder may or may not support
            a particular type of input or output. For example, the image
            transcoders accept an SVG
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Document.html">Document</a>,
            a
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/Reader.html">Reader</a>,
            an
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/InputStream.html">InputStream</a>,
            or a
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html">URI</a>
            as an input but only supports a byte stream for the output.
          </p>
        </dd>

        <dt>TranscoderInput</dt>
        <dd>
          <p>
            The
            <a class="class" href="../javadoc/org/apache/batik/transcoder/TranscoderInput.html">TranscoderInput</a>
            interface defines the input of a transcoder. There are various ways to create an
            input and the most common are already part of the API. The default
            implementation lets you create an input using a
            <code>org.w3c.dom.Document</code>, a <code>Reader</code>, an
            <code>InputStream</code>, a <code>org.xml.sax.XMLReader</code>, or a
            <code>URI</code>.
          </p>
        </dd>

        <dt>TranscoderOutput</dt>
        <dd>
          <p>
            The
            <a class="class" href="../javadoc/org/apache/batik/transcoder/TranscoderOutput.html">TranscoderOutput</a>
            interface defines the output of a transcoder. There are various ways to create an
            output and the most commons are already part of the API. The default
            implementation lets you create an output using a
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Document.html">Document</a>,
            a
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/Writer.html">Writer</a>,
            an
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/OutputStream.html">OutputStream</a>,
            a
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/XMLFilter.html">XMLFilter</a>,
            or a
            <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html">URI</a>.
          </p>
        </dd>

        <dt>TranscodingHints</dt>
        <dd>
          <p>
            The
            <a class="class" href="../javadoc/org/apache/batik/transcoder/TranscodingHints.html">TranscodingHints</a>
            class contains different hints that can be used to control
            the various options or parameters of a transcoder. Each transcoder
            provides its own set of hints. A hint is specified by (key, value)
            pair. For example, the
            <a class="class" href="../javadoc/org/apache/batik/transcoder/image/JPEGTranscoder.html">JPEGTranscoder</a>
            provides a hint to control the encoding quality.
          </p>
        </dd>

        <dt>ErrorHandler</dt>
        <dd>
          <p>
            The
            <a class="class" href="../javadoc/org/apache/batik/transcoder/ErrorHandler.html">ErrorHandler</a>
            class provides a way to get any errors or warnings that might
            occur while transcoding. A default implementation is provided but
            you can, for example, implement your own handler that displays a dialog
            instead of stack trace.
          </p>
        </dd>
      </dl>
    </section>

    <section id="howtousetranscoderAPI">
      <title>How to use the image transcoder API</title>
      <p>
        The <code>org.apache.batik.transcoder.image</code> package provides an
        easy way to transcode an SVG document to a raster image such as JPEG,
        PNG or TIFF. Additional raster image formats can be added by
        subclassing the <code>ImageTranscoder</code> class and implementing the
        <code>writeImage</code> method. Although, in next sections, the
        examples will use the JPEG transcoder, the PNG transcoder works the
        same way.
      </p>

      <section id="createImage">
        <title>Creating an image</title>
        <p>
          The following example, using the <code>JPEGTranscoder</code>, shows how to
          transform an SVG document to a JPEG image.
        </p>
      <source>import java.io.*;

import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;

public class SaveAsJPEG {

    public static void main(String[] args) throws Exception {

        // Create a JPEG transcoder
        <strong>JPEGTranscoder t = new JPEGTranscoder();</strong>

        // Set the transcoding hints.
        <strong>t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
                             new Float(.8));</strong>

        // Create the transcoder input.
        String svgURI = new File(args[0]).toURL().toString();
        <strong>TranscoderInput input = new TranscoderInput(svgURI);</strong>

        // Create the transcoder output.
        OutputStream ostream = new FileOutputStream("out.jpg");
        <strong>TranscoderOutput output = new TranscoderOutput(ostream);</strong>

        // Save the image.
        <strong>t.transcode(input, output);</strong>

        // Flush and close the stream.
        ostream.flush();
        ostream.close();
        System.exit(0);
    }
}</source>
      <p>
        The code creates a <code>JPEGTranscoder</code> and sets a
        transcoding hint. The hint indicates the encoding quality. Then, an
        input and an output are created. The input is created using the first
        command line argument, which should be a URI. The output is a byte
        stream for a file called <code>out.jpg</code>. Finally, the
        <code>transcode</code> method is invoked and the byte stream is
        closed.
      </p>
      <p>
        Although not shown above, the program might have specified additional
        hints to indicate a user stylesheet, the preferred language of the
        document or the background color.
      </p>
      <p>
        To try this program:
      </p>
      <ol>
        <li>
          <p>Save the above program as <code>SaveAsJPEG.java</code>. </p>
        </li>
        <li>
          <p>Compile the program.</p>
        </li>
        <li>
          <p>Choose an SVG file to transcode, and perform the transcoding by running:</p>
          <source>java SaveAsJPEG <em>filename</em>.svg</source>
        </li>
        <li>
          <p>Inspect the output file <code>out.jpg</code>.</p>
        </li>
      </ol>
    </section>

    <section id="defineSizeOfImage">
      <title>Defining the size of the image</title>
      <p>
        By adding the following line of code to the previous example, you will
        specify the raster image size (in pixels). The transcoding hint
        <code>KEY_WIDTH</code> lets you specify the raster image width. If the
        raster image height is not provided (using the <code>KEY_HEIGHT</code>),
        the transcoder will compute the raster image height by keeping the
        aspect ratio of the SVG document.
      </p>
      <source>t.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float(100));</source>
      <p>
        The transcoder will have the same behavior if you specify the
        <code>KEY_HEIGHT</code> without initializing the
        <code>KEY_WIDTH</code>. In all cases (even if both keys are provided),
        the transcoder will preserve the apsect ratio of the SVG document.
      </p>
    </section>

    <section id="selectAreaOfIntrest">
      <title>Selecting an area of interest</title>
      <p>
        The image transcoder lets you specify an area of interest (that is, a
        part of the SVG document). The key <code>KEY_AOI</code> allows you to
        select the region of the SVG document to render. The value of this key must
        be a
        <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Rectangle.html">java.awt.Rectangle</a>
        specified in pixels, using the coordinate space of the SVG document. The
        following example shows how you can split an SVG document into 4 tiles.
      </p>
      <source>import java.io.*;
import java.awt.*;

import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;

public class SaveAsJPEGTiles {

    JPEGTranscoder trans = new JPEGTranscoder();

    public SaveAsJPEGTiles() {
        trans.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
                                 new Float(.8));
    }

    public void tile(String inputFilename,
                     String outputFilename,
                     Rectangle aoi) throws Exception {
        // Set hints to indicate the dimensions of the output image
        // and the input area of interest.
        <strong>trans.addTranscodingHint(JPEGTranscoder.KEY_WIDTH,
                                 new Float(aoi.width));</strong>
        <strong>trans.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT,
                                 new Float(aoi.height));</strong>
        <strong>trans.addTranscodingHint(JPEGTranscoder.KEY_AOI, aoi);</strong>

        // Transcode the file.
        String svgURI = new File(inputFilename).toURL().toString();
        TranscoderInput input = new TranscoderInput(svgURI);
        OutputStream ostream = new FileOutputStream(outputFilename);
        TranscoderOutput output = new TranscoderOutput(ostream);
        trans.transcode(input, output);

        // Flush and close the output.
        ostream.flush();
        ostream.close();
    }

    public static void main(String[] args) throws Exception {
        // Rasterize the samples/anne.svg document and save it
        // as four tiles.
        SaveAsJPEGTiles p = new SaveAsJPEGTiles();
        <strong>String in = "samples/anne.svg";
        int documentWidth = 450;
        int documentHeight = 500;</strong>
        int dw2 = documentWidth / 2;
        int dh2 = documentHeight / 2;
        p.tile(in, "tileTopLeft.jpg", new Rectangle(0, 0, dw2, dh2));
        p.tile(in, "tileTopRight.jpg", new Rectangle(dw2, 0, dw2, dh2));
        p.tile(in, "tileBottomLeft.jpg", new Rectangle(0, dh2, dw2, dh2));
        p.tile(in, "tileBottomRight.jpg", new Rectangle(dw2, dh2, dw2, dh2));
        System.exit(0);
    }
}</source>
      <p>
        This code splits the same document <code>anne.svg</code> into four
        tiles of the same size. Considering the document and its original
        size, we can determine four regions. Then we rasterize each region
        using the <code>KEY_AOI</code> key. Note that we also specify the
        image width and height to be the same as the area of interest width and
        height (so we keep a 1:1 zoom factor). You can of course use different
        values for the <code>KEY_WIDTH</code> and <code>KEY_HEIGHT</code>, that
        do not match the dimensions of the <code>KEY_AOI</code> key. In that
        case, first the area of interest will determine which part of the SVG
        document has to be rendered, then that part could be zoomed in or out
        depending on the specified raster image size.
      </p>
      <p>
        To try this program:
      </p>
      <ol>
        <li><p>Save the above program as <code>SaveAsJPEGTiles.java</code>.</p></li>
        <li><p>Compile the program.</p></li>
        <li><p>Copy the <code>samples/anne.svg</code> document from the Batik
            distribution into the current directory.</p></li>
        <li>
          <p>Run the program by typing:</p>
          <source>java SaveAsJPEGTiles</source>
        </li>
        <li>
          <p>
            Inspect the output files <code>tileTopRight.jpg</code>,
            <code>tileTopRight.jpg</code>, <code>tileBottomRight.jpg</code>
            and <code>tileBottomLeft.jpg</code>.
          </p>
        </li>
      </ol>
    </section>

    <section id="otherTransHints">
      <title>Other transcoding hints</title>
      <p>
        The <code>ImageTranscoder</code> provides additional
        <code>TranscodingHints</code> that let you customize the generated
        images.
      </p>
      <dl>
        <dt><code>ImageTranscoder.KEY_MEDIA</code></dt>
        <dd>
          <p>
            This hint lets you choose the CSS medium to use. The author of the SVG document
            to transcode can control CSS media using the
            <a href="http://www.w3.org/TR/REC-CSS2/media.html">CSS media rule</a>.
            For example:
          </p>
          <source>trans.addTranscodingHint(ImageTranscoder.KEY_MEDIA, "print");</source>
        </dd>

        <dt><code>ImageTranscoder.KEY_ALTERNATE_STYLESHEET</code></dt>
        <dd>
          <p>
            This hint lets you choose an alternate stylesheet the author of the SVG
            document to transcode might have provided using the
            <a href="http://www.w3.org/TR/xml-stylesheet/">xml-stylesheet</a>
            processing instruction. For exxample:
          </p>
          <source>trans.addTranscodingHint(ImageTranscoder.KEY_ALTERNATE_STYLESHEET,
                         alternateStylesheetName);</source>
        </dd>

        <dt><code>ImageTranscoder.KEY_USER_STYLESHEET_URI</code></dt>
        <dd>
          <p>
            This hint lets you use a user stylesheet. A user stylesheet can override some
            styles of the SVG document to transcode. For example:
          </p>
          <source>trans.addTranscodingHint(ImageTranscoder.KEY_USER_STYLESHEET_URI, "http://...");</source>
        </dd>

        <dt><code>ImageTranscoder.KEY_PIXEL_TO_MM</code></dt>
        <dd>
          <p>
            This hint lets you use the pixel to millimeter conversion factor.
            This factor is used to determine how units are converted into
            pixels.  For example:
          </p>
          <source>// 96dpi
trans.addTranscodingHint(ImageTranscoder.KEY_PIXEL_TO_MM, new Float(0.2645833f));</source>
          <p>or</p>
          <source>// 72pi
trans.addTranscodingHint(ImageTranscoder.KEY_PIXEL_TO_MM, new Float(0.3528f));</source>
        </dd>

        <dt><code>ImageTranscoder.KEY_BACKGROUND_COLOR</code></dt>
        <dd>
          <p>
            This hint lets you choose a background color. For example:
          </p>
          <source>trans.addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, Color.white);</source>
        </dd>
      </dl>
    </section>

    <section id="genImagefromSVGDOM">
      <title>Generating an image from an SVG DOM tree</title>
      <p>
        The following code creates and saves an SVG DOM tree to
        a raster image.
      </p>
<source>import java.io.*;

import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.dom.svg.SVGDOMImplementation;

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

public class DOMRasterizer {

    public Document createDocument() {

        // Create a new document.
        <strong>DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
        String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
        Document document =
            impl.createDocument(svgNS, "svg", null);
        Element root = document.getDocumentElement();</strong>
        root.setAttributeNS(null, "width", "450");
        root.setAttributeNS(null, "height", "500");

        // Add some content to the document.
        Element e;
        e = document.createElementNS(svgNS, "rect");
        e.setAttributeNS(null, "x", "10");
        e.setAttributeNS(null, "y", "10");
        e.setAttributeNS(null, "width", "200");
        e.setAttributeNS(null, "height", "300");
        e.setAttributeNS(null, "style", "fill:red;stroke:black;stroke-width:4");
        root.appendChild(e);

        e = document.createElementNS(svgNS, "circle");
        e.setAttributeNS(null, "cx", "225");
        e.setAttributeNS(null, "cy", "250");
        e.setAttributeNS(null, "r", "100");
        e.setAttributeNS(null, "style", "fill:green;fill-opacity:.5");
        root.appendChild(e);

        return document;
    }

    public void save(Document document) throws Exception {

        // Create a JPEGTranscoder and set its quality hint.
        JPEGTranscoder t = new JPEGTranscoder();
        t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
                             new Float(.8));

        // Set the transcoder input and output.
        <strong>TranscoderInput input = new TranscoderInput(document);</strong>
        OutputStream ostream = new FileOutputStream("out.jpg");
        TranscoderOutput output = new TranscoderOutput(ostream);

        // Perform the transcoding.
        t.transcode(input, output);
        ostream.flush();
        ostream.close();
    }

    public static void main(String[] args) throws Exception {
        // Runs the example.
        DOMRasterizer rasterizer = new DOMRasterizer();
        Document document = rasterizer.createDocument();
        rasterizer.save(document);
        System.exit(0);
    }
}
</source>
      <p>
        This code is divided into two distinct parts. 
      </p>
      <dl>
        <dt>Creating an SVG DOM tree</dt>
        <dd>
          <p>See the <code>createDocument</code> method.</p>
          <p>
            Three steps are required at this time. The first step is to
            get the Batik SVG DOM implementation (via the
            <code>SVGDOMImplementation</code> class). Then, you can create a
            <code>org.w3c.dom.Document</code> (which also implements the
            <code>SVGDocument</code> interface) by invoking the
            <code>createDocument</code> method with the SVG namespace URI and
            the <code>svg</code> document element name. Finally, you can get
            the document element and start building your DOM tree.
          </p>
        </dd>
        <dt>Rasterizing the DOM</dt>
        <dd>
          <p>See the <code>save</code> method.</p>
          <p>
            Similar to the previous examples, you can transcode an SVG
            document to a raster image by creating a
            <code>TranscoderInput</code>, but passing to it the SVG Document
            this time.
          </p>
        </dd>
      </dl>
      <p>
        To try this example:
      </p>
      <ol>
        <li><p>Save the code as <code>DOMRasterizer.java</code>.</p></li>
        <li><p>Compile the program.</p></li>
        <li><p>Run it, by typingL</p>
          <source>java DOMRasterizer</source></li>
        <li><p>Inspect the output file <code>out.jpg</code>.</p></li>
      </ol>
    </section>
  </section>

</body>
</document>
