I built a client side javascript SVG to PNG converter that works on *modern* browsers, however, depending on your target audience the browsers that frequent your site may be less than modern – i.e. IE. In this situation you only have one option, convert the image on the server side and then render it using the good old image tag.
First, cold fusion ships with some outdated batik files (which handle the cfimage tag) , so you will need to update those first, and add the missing files that will add your svg to -> image processing ability. I used the steps found in this post to accomplish the task; I’ll list them here in short format so you can get into the ext chart part of this project.
- Stop your cold fusion service
- Download the files from the batik website http://xmlgraphics.apache.org/batik/download.cgi
- Rename the jar files in /wwwroot/WEB-INF/cfform/jars/ that start with batik by adding the extension .old
- Copy the batik jar files into /wwwroot/WEB-INF/lib
- Restart Cold Fusion
Next, let’s assume that we have two files, one called convertImage.cfm and one called convertImage.cfc, of course, we want to pass the svg markup to the cfm which will pass the data to the cfc for processing.
<cfcase value="saveChart">
<cfset saveChart = data.saveChart( svg=form.svg) />
<cfset json = "{'success':'#saveChart#'}" />
</cfcase>
The code below goes in the cfc file.
<cffunction name="saveChart" >
<cfargument name="svg" />
<cftry>
<cfset svgFile = "c:\websites\temp.svg" />
<cfset jpgFile = replace("c:\websites\temp.svg", ".svg", ".jpg") />
<cfset pngFile = (pngPath) />--->
<cffile action="delete" file="c:\websites\temp.jpg" >
<cfif FileExists(svgFile)>
<cffile action="delete" file="c:\websites\temp.svg" >
<cffile action="write" file="c:\websites\temp.svg" output="#svg#" >
<cfelse>
<cffile action="write" file="c:\websites\temp.svg" output="#svg#" >
</cfif>
<cfset t = createObject("java", "org.apache.batik.transcoder.image.JPEGTranscoder").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(jpgFile) />
<cfset output = createObject("java", "org.apache.batik.transcoder.TranscoderOutput").init(ostream) />
<cfset t.transcode(input, output) />
<cfset ostream.flush() />
<cfset ostream.close() />
<cfcatch type="any">
<cfreturn "false" />
</cfcatch>
</cftry>
<cfreturn "true" />
</cffunction>
The function below would go in your javascript controller.
saveChart: function(me){
this.dTask.delay(500, function(){
var svg = me.up('panel').down('chart').save(
{
type :'image/svg+xml'
}
);
Ext.Ajax.request({
url: 'convertImage.cfm?remoteEvent=saveChart',
params: {
svg: svg
},
success: function(){
// process server response here
window.open('temp.jpg');
}
});
});
},