1. 程式人生 > >SVG2PNG(前臺個後臺將SVG轉換為PNG,完美支持IE8下載)--amcharts導出png

SVG2PNG(前臺個後臺將SVG轉換為PNG,完美支持IE8下載)--amcharts導出png

doc 項目 commons cep finall 保存 格式 lose 矢量圖形

  

  在項目中用到了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>
<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> </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