You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by Jon Bråtøymyr <Jo...@Finansbanken.no> on 2001/06/26 13:24:29 UTC

Problems with DOMUtilities / ImageTranscoder

Hi,

I'm having problems with creating an image from a plain
org.w3c.dom.Document. I was told that I could use
DOMUtilities.deepCloneDocument to convert a w3c-Document to a SVGDocument,
but when I run the transcoding I get a ClassCastException. Apparently when
the ImageTranscoder tries to cast the root element to
org.apache.batik.dom.GenericElement.

I'm using a very simple XML in this example to illustrate my problem,
normally I would run a XSL transformation on a Document containing financial
information to create a JPEG image in a report (that is created with an
other transformation on the same source). 

Now I must convert the resulting Document into a String before I give it to
Batik, not a very effective process I would believe...

Below is some sample code that illustrates my problem, as well as the
exception I get. Can anyone see if I'm doing anything wrong?

Thanks,
- Jon



import org.apache.xerces.parsers.*;
import org.apache.batik.transcoder.image.*;
import org.apache.batik.transcoder.*;
import org.apache.batik.dom.util.*;
import org.apache.batik.dom.svg.*;
import org.xml.sax.*;
import org.w3c.dom.*;
import java.io.*;

public class BatikTest {
    public static void main (String args[]) throws Exception {
        final String XML = "<svg><circle cx=\"100\" cy=\"100\" r=\"50\"
style=\"fill:green\"/></svg>";
        DOMParser   parser      = new DOMParser();
        InputSource inputSource = new InputSource(new StringReader(XML));
        parser.parse(inputSource);
        Document SVG = parser.getDocument();        
        Document SVGDOM = DOMUtilities.deepCloneDocument(SVG,
SVGDOMImplementation.getDOMImplementation());        
        TranscoderInput  in  = new TranscoderInput(SVGDOM);
        FileOutputStream f = new FileOutputStream("d:\\svgtest.jpg");
        TranscoderOutput out = new TranscoderOutput(f);
        Transcoder transcoder = new JPEGTranscoder();
 
transcoder.addTranscodingHint(ImageTranscoder.KEY_XML_PARSER_CLASSNAME,
"org.apache.xerces.parsers.SAXParser");
        transcoder.transcode(in, out);
        f.flush();
        f.close();
    }
}
The above code gives the following exception when I try to execute it (it
fails at the line transcoder.transcode(in, out);) :

java.lang.ClassCastException: org.apache.batik.dom.GenericElement
        at
org.apache.batik.dom.svg.SVGOMDocument.getRootElement(SVGOMDocument.java:519
)
        at
org.apache.batik.transcoder.image.ImageTranscoder.transcode(ImageTranscoder.
java:142)
        at
org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTrans
coder.java:126)
        at com.accenture.jam.xml.BatikTest.main(BatikTest.java:26)


I'm using JDK1.3 on Windows NT and Batik 1.0



Re: Problems with DOMUtilities / ImageTranscoder

Posted by Peter Becker <pb...@meganesia.int.gu.edu.au>.
Thierry Kormann wrote:
> 
> On Tuesday 26 June 2001 14:34, Peter Becker wrote:
> > Jon Bråtøymyr wrote:
> > > Hi,
> > >
> > > I'm having problems with creating an image from a plain
> > > org.w3c.dom.Document. I was told that I could use
> > > DOMUtilities.deepCloneDocument to convert a w3c-Document to a
> > > SVGDocument, but when I run the transcoding I get a ClassCastException.
> > > Apparently when the ImageTranscoder tries to cast the root element to
> > > org.apache.batik.dom.GenericElement.
> 
> I think you might have used the method with an appropriate argument.
> You must give the original document and then the DOMImplementation you want
> to use.
> 
> The document is the one you have (that can be from xerces, generic DOM or
> whatever) then the DOMImplementation must be the SVGDOMImplementation.
> 
> DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();

Even if this repeats Jons code more or less exactly, here is my try:

<code>
            org.jdom.adapters.DOMAdapter domAdapter = new
org.jdom.adapters.XercesDOMAdapter();
            org.jdom.output.DOMOutputter out = new
org.jdom.output.DOMOutputter();
            org.w3c.dom.Document w3cdoc = domAdapter.createDocument();
            org.w3c.dom.Node root = w3cdoc.importNode( out.output(
_svgElement ), true );
            w3cdoc.appendChild( root );

            org.w3c.dom.DOMImplementation impl =
org.apache.batik.dom.svg.SVGDOMImplementation.getDOMImplementation();
            org.w3c.dom.Document svgDoc =
org.apache.batik.dom.util.DOMUtilities.deepCloneDocument(w3cdoc, impl);

            ImageTranscoder t;
            if( target.toString().endsWith( ".jpg" ) ||
                target.toString().endsWith( ".jpeg" ) )
            {
                // create a JPEG transcoder
                t = new JPEGTranscoder();
                // set the transcoding hints
                t.addTranscodingHint(
JPEGTranscoder.KEY_XML_PARSER_CLASSNAME,
                                     
"org.apache.crimson.parser.XMLReaderImpl" );
                t.addTranscodingHint( JPEGTranscoder.KEY_QUALITY,
                                      new Float(.8) );
            }
            else if( target.toString().endsWith( ".png" ) )
            {
                // create a PNG transcoder
                t = new PNGTranscoder();
                // set the transcoding hints
                t.addTranscodingHint(
PNGTranscoder.KEY_XML_PARSER_CLASSNAME,
                                     
"org.apache.crimson.parser.XMLReaderImpl" );
            }
            else
            {
                throw new ImageGenerationException( "Image '" +
target.toString() +
                                "' could not be generated: unknown
extension" );
            }

            // create the transcoder input
            TranscoderInput input = new TranscoderInput( svgDoc );
            // create the transcoder output
            OutputStream ostream = new FileOutputStream( target );
            TranscoderOutput output = new TranscoderOutput( ostream );
            // save the image
            t.transcode( input, output );
            // flush and close the stream
            ostream.flush();
            ostream.close();
</code>

(sorry about all the package names, but I knew I would have to remove it
later ;-) )

and here is the result:

<output>
java.lang.ClassCastException: org.apache.batik.dom.GenericElementNS

	at
org.apache.batik.dom.svg.SVGOMDocument.getRootElement(SVGOMDocument.java:519)

	at
org.apache.batik.transcoder.image.ImageTranscoder.transcode(ImageTranscoder.java:142)

	at
org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:126)

	at
net.sourceforge.xweb.backend.images.SVGImageGenerator.createImageFileInternal(SVGImageGenerator.java:176)

	at 
	<skip/>
</output>

Exactly Jon's problem and what I wrote some time ago.

> BTW: We could not rely on a generic DOM implementation at least for building
> and rendering SVG documents because SVG is complex and needs special hooks.
> The best example is to implement external <use> element with the correct
> cascading algorithm for the CSS properties.

As said in the other thread: then either don't claim to accept the
generic interfaces or just fall back into a less performant mode, e.g.
like this:

<code implemented="false">
    public TranscoderInput(Document document) {
        if( document instanceof SVGDocument ) {
            this.document = document;
        }
        else {
            this.document = DOMUtilities.deepCloneDocument(document,
impl);
        }
    }
</code>

where impl is an instance of your DOMImplementation and the
deepCloneDocument works. This should be easy to do (if the cloning
works), you can add a hint on the performance problem to the JavaDoc.
Jon, you and I would have saved hours.

So currently I have to stick with my temp files which sometimes just
won't get deleted but otherwise are not a big issue for me, but surely
are if you want to use a dynamic environment and not the more
compilerlike approach of XWeb.

BTW: I finished the first version of my Java rant *g* See:
   http://www.peterbecker.de/texts/javacritique.html

Batik has many of the flaws mentioned there :-(

HTH,
  PeterB

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Re: Problems with DOMUtilities / ImageTranscoder

Posted by Thierry Kormann <tk...@ilog.fr>.
On Tuesday 26 June 2001 14:34, Peter Becker wrote:
> Jon Bråtøymyr wrote:
> > Hi,
> >
> > I'm having problems with creating an image from a plain
> > org.w3c.dom.Document. I was told that I could use
> > DOMUtilities.deepCloneDocument to convert a w3c-Document to a
> > SVGDocument, but when I run the transcoding I get a ClassCastException.
> > Apparently when the ImageTranscoder tries to cast the root element to
> > org.apache.batik.dom.GenericElement.

I think you might have used the method with an appropriate argument.
You must give the original document and then the DOMImplementation you want 
to use.

The document is the one you have (that can be from xerces, generic DOM or 
whatever) then the DOMImplementation must be the SVGDOMImplementation.

DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();


BTW: We could not rely on a generic DOM implementation at least for building 
and rendering SVG documents because SVG is complex and needs special hooks. 
The best example is to implement external <use> element with the correct 
cascading algorithm for the CSS properties.

Hope this helps,
Thierry.

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Re: Problems with DOMUtilities / ImageTranscoder

Posted by Peter Becker <pb...@meganesia.int.gu.edu.au>.
Jon Bråtøymyr wrote:
> 
> Hi,
> 
> I'm having problems with creating an image from a plain
> org.w3c.dom.Document. I was told that I could use
> DOMUtilities.deepCloneDocument to convert a w3c-Document to a SVGDocument,
> but when I run the transcoding I get a ClassCastException. Apparently when
> the ImageTranscoder tries to cast the root element to
> org.apache.batik.dom.GenericElement.
> 
> I'm using a very simple XML in this example to illustrate my problem,
> normally I would run a XSL transformation on a Document containing financial
> information to create a JPEG image in a report (that is created with an
> other transformation on the same source).
> 
> Now I must convert the resulting Document into a String before I give it to
> Batik, not a very effective process I would believe...
> 
> Below is some sample code that illustrates my problem, as well as the
> exception I get. Can anyone see if I'm doing anything wrong?

AFAIK not -- at least I ended up with the same approach for my website
generation program. Batik often claims to take generic DOM but assumes
to get its own implementation.

You can find the thread I started on this topic here:
  
http://www-sop.inria.fr/koala/batik/mlists/batik-users/archives/msg00213.html

Since I don't create the SVGs dynamically it is not a big issue for me,
but by now I create more than 100 buttons/banners for one site and then
it takes really long -- longer than the actual XSLT processing :-( Most
of them are even really simple SVGs that just paint a rectangle, a small
path and some text. I didn't try any benchmarking yet, but the
additional file is surely quite expensive, esp. in Java.

Unfortunately I won't have time to address this issue myself -- at least
not in the next weeks.

Regards,
   PeterB

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org