SVG2PNG(前臺個後臺將SVG轉換為PNG,完美支持IE8下載)--amcharts導出png
在項目中用到了amcharts,amcharts圖標統計插件是利用SVG實現的,其自帶下載png功能,但是不支持IE以下瀏覽器。因此研究了SVG轉換為png,最終實現的效果是將amcharts生成一張png寫入一個excel並提供下載。
1.SVG簡介:
SVG 意為可縮放矢量圖形(Scalable Vector Graphics)。說白了就是利用xml定義圖形。
SVG 使用 XML 格式定義圖像。
例如一個簡單的圓形:
<html> <body> <h1>My first SVG</h1> <svgxmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> </svg> </body> </html>
結果:
註意:如果將SVG的父標簽去掉也是正常使用的,比如:(用瀏覽器打開後綴為下面後綴為SVG的文件)
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> </svg>
結果:
但是如果將SVG根標簽的xmlns屬性去掉是不會顯示為圖形的,比如:
<svg version="1.1"> <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> </svg>
總結:SVG如果正常顯示為圖形,需要在SVG根標簽引入 xmlns="http://www.w3.org/2000/svg"
更多的關於SVG的使用參考菜鳥教程:http://www.runoob.com/svg/svg-tutorial.html
2.SVG轉換為PNG
會研究前臺JS生成和後臺利用batik生成png。所有用到的JS以及lib或者其他會在最後提供github連接。
2.1前臺轉換(不支持IE)
需要的JS:saveSvgAsPng.js ,前臺下載也比較簡單。支持chrome、firefox等主流瀏覽器(Ie就不主流了。。。。。)
簡單的測試:
<html> <body> <h1>My first SVG</h1> <div> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="testSvg"> <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> </svg> </div> <button onclick="downloadSvg()">download</button> </body> <script src="saveSvgAsPng.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> function downloadSvg(){ //下載的方法--第一個參數是SVG的頂級元素,第二個參數是文件名字 saveSvgAsPng(document.getElementById("testSvg"), "diagram.png"); } </script> </html>
2.2後臺將SVG轉換為PNG
後臺轉換也就是將SVGCODE轉換為PNG,註意SVGCODE是需要xmlns屬性的,否則會轉換失敗:
1.依賴的jar包:(commons-io包是為了讀取svgcode)
2.工程結構
3. 需要轉換的SVGCODE:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> </svg>
直接瀏覽器打開效果:
4.轉換的代碼以及測試:
package cn.qlq.svg2png; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.ImageTranscoder; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.commons.io.FileUtils; /** * 將svg轉換為png格式的圖片 * * */ public abstract class SVG2PNGUtils { /** * 將svg字符串轉換為png * * @param svgCode * svg代碼 * @param pngFilePath * 保存的路徑 * @throws TranscoderException * svg代碼異常 * @throws IOException * io錯誤 */ public static void convertToPng(String svgCode, String pngFilePath) throws IOException, TranscoderException { File file = new File(pngFilePath); FileOutputStream outputStream = null; try { file.createNewFile(); outputStream = new FileOutputStream(file); convertToPng(svgCode, outputStream); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 將svgCode轉換成png文件,直接輸出到流中 * * @param svgCode * svg代碼 * @param outputStream * 輸出流 * @throws TranscoderException * 異常 * @throws IOException * io異常 */ public static void convertToPng(String svgCode, OutputStream outputStream) throws TranscoderException, IOException { try { byte[] bytes = svgCode.getBytes("utf-8"); PNGTranscoder t = new PNGTranscoder(); TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(bytes)); TranscoderOutput output = new TranscoderOutput(outputStream); // 增加圖片的屬性設置(單位是像素)---下面是寫死了,實際應該是根據SVG的大小動態設置,默認寬高都是400 t.addTranscodingHint(ImageTranscoder.KEY_WIDTH, new Float(941)); t.addTranscodingHint(ImageTranscoder.KEY_HEIGHT, new Float(800)); t.transcode(input, output); outputStream.flush(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws IOException, TranscoderException { ClassLoader classLoader = SVG2PNGUtils.class.getClassLoader(); String filePath = classLoader.getResource("cn/qlq/svg2png/svgtest.svg").getPath(); String svgCode = FileUtils.readFileToString(new File(filePath), "UTF-8"); convertToPng(svgCode, "e:/test.png"); } }
結果會生成PNG。(再次強調SVG文件的xmlns一定要寫)
至此就實現了SVG轉換為PNG,在web應用中我們可以將SVGCODE傳到後臺處理之後生成一個PNG並提供下載,再深入一點可以將圖片再寫入excel中提供下載。
SVG2PNG(前臺個後臺將SVG轉換為PNG,完美支持IE8下載)--amcharts導出png