ColdFusion and Batik

I've been using SVG for custom charting stuff for several years now,
and it's really nice. Only problem is that it requires an SVG
plugin, and it's not very common. No big deal for admin sites,
but for more public usage, that's pretty much a concept killer.

Enter Batik.

Batik is a Java SVG implementation by the Apache Group that, aside
from rendering SVG, has a lot of really neat supporting tools.
One of them is a group of transcoders that'll take an SVG file and turn
it into an image. Do that, and suddenly your SVG charts are
consumable by the general public. Obviously the transcoders don't
do the animation and scripting that SVG supports, but for charts,
that's no big deal.

Installation is a snap, though CF7 has a partial Batik package
included that needs to be moved out of the way first. Both
standalone and multiserver installs should have a WEB-INF/cfform/jars
directory with a few batik-*.jar files. Those need to be moved
away (I opted for putting them in a new WEB-INF/cfform/batik-jars
directory), and then a full Batik package needs to be installed.
For standalone, I found $cfroot/lib to be optimal, and on multiserver
they should go in WEB-INF/lib.

Once done, all you need is a bit of magic like this:

<cfset svgPath = "test.svg" />
<cfset pngPath = "test.png" />
<cfset svgFile = expandPath(svgPath) />
<cfset pngFile = expandPath(pngPath) />
<cfset t = createObject("java", "org.apache.batik.transcoder.image.PNGTranscoder").init() />
<cfset svgURI = createObject("java", "java.io.File").init(svgFile).toURL().toString() />
<cfset input = createObject("java", "org.apache.batik.transcoder.TranscoderInput").init(svgURI) />
<cfset ostream = createObject("java", "java.io.FileOutputStream").init(pngFile) />
<cfset output = createObject("java", "org.apache.batik.transcoder.TranscoderOutput").init(ostream) />
<cfset t.transcode(input, output) />
<cfset ostream.flush() /> <cfset ostream.close() />

<cfoutput>
<embed src="#svgPath#" width="1024" height="265" type="image/svg+xml" />
<img src="#pngPath#" />
</cfoutput>

You will, of course, want to update the width and height on the
EMBED tag to match your file. I haven't tested any of this on
CF6, but it should be even simpler, since there doesn't appear to be
the partial Batik install that needs to be moved out of the way.

As near as I can tell, CF itself isn't any worse for wear with the updated
Batik, though I can't say I've tested very thoroughly.

3 Responses to “ColdFusion and Batik”


  1. 1 Dave Ross

    I hit this recently as well, we have a lot of apps written on 6.1 that generate PDFs with Apache FOP, which requires batik. We didn't know we had an issue until someone tried to write flash forms… oddly enough I found out that batik was the problem by searching a Flex list.

  2. 2 Amy

    Thanks for this post - it has really helped me, however, I am still having trouble with the embed tag. It keeps returning Object Not Found. I can display the img perfectly, but I want to be able to embed the svg file that was created in case the user does have the SVG Viewer installed.
    Can you help? Thanks alot.

  3. 3 barneyb

    Amy,

    I'd suspect a file pathing issue with the SVG file. The example assumes the simple case of everything being in the same directory, and that directory being accessed directly from the URL (i.e. not through a front controller such as Fusebox that dissociates URL paths to file paths). However, if the PNG file works, the SVG file ought to as well. Have you confirmed that they're both being written in the locations you think they're being written?

Leave a Reply