I've created a GIF transcoder class which extends the PNGTranscoder class, but returns the images as GIF rather than PNG. Preferably I'd want to override a class that rendered to a BufferedImage, which I could then use directly with the gif creation library I'm using (http://www.fmsware.com/stuff/gif.html).

The main reason for doing so is to produce animated GIFs from SVGs. Basically the idea is to call the transcoder multiple times, once for each frame in the loop, specifying the KEY_SNAPSHOT_TIME hint to the transcoder each time to get a PNG image for that moment in time. The image results from those multiple calls to transcode() are then packaged together and passed back out of the transcode() call as an assembled animated GIF.

The first frame renders perfectly. Any frames after that appear in what I'm going to call the 'default' state. That is, I've setup the SVG animation with some moving text. The text element itself is positioned at the top left of the viewport. The animation starts at 0 seconds, with an initial point for the text near the middle of the viewport, then sliding the the bottom right during the animation. The first frame shows with the text at the animation path start point. Following frames show the text positioned at the coordinates specified in the text element, not the initial animation path location.

I have found that if I convert the TranscoderInput to a UTF8 byte array, then create a new TranscoderInput and Document object based on the byte array for each frame that it outputs properly. This is fast enough on a small SVG like the example with this message, however our usage of it requires that it deal with svg images that can get rather large in size due to embedded fonts and images.

Recreating that document each frame can be a considerable overhead as it accounts for a good portion of rendering time for a frame in my testing.

Is there some way I can reset the document to its initial state without recreating it? Is there a faster way to clone the document, its my understanding that .clone() won't do what I need.

I'm using the batik 1.7 distribution.


This is the code I use currently which only renders the first frame correctly, all other frames are in a 'default' state as if animation/onload was disabled:

|@Override
void transcode(TranscoderInput input, TranscoderOutput output) {
   int animationFrameCount = 5;
   float firstFrameTime = 0.0f;
   float timeStep = 0.0f;


java.io.ByteArrayOutputStream gifStream = new java.io.ByteArrayOutputStream();
   gif4free.AnimatedGifEncoder e = new gif4free.AnimatedGifEncoder();
   e.start(gifStream);

   for (int i = 0; i < animationFrameCount; i++) {
       tmpStream = new java.io.ByteArrayOutputStream();
       oto = new org.apache.batik.transcoder.TranscoderOutput(tmpStream);
super.addTranscodingHint(KEY_SNAPSHOT_TIME, new Float((firstFrameTime+(i * timeStep))).intValue().toString());
       super.transcode(input, oto);
       super.removeTranscodingHint(KEY_SNAPSHOT_TIME);
e.addFrame(||javax.imageio.ImageIO.read(new java.io.ByteArrayInputStream(||tmpStream.toByteArray()||))||);
   }
   e.finish();
   gifStream.flush();
   gifStream.close();
   gifStream.writeTo(output.getOutputStream());
}||
|

SVG Test image used to recreate the problem:

||<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd";>
<svg width="300" height="300" viewBox="0 0 300 300"
xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink";>
   <title>DGS animation example for {Company:Name}</title>
   <rect x="0" y="0" width="300" height="300" fill="#FFFFFF"/>
   <text x="42" y="42">Sliding Text
<animateMotion path="M 42 42 L 188 243" begin="0s" dur="5s" fill="freeze" />
   </text>
</svg>
||


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to