2016-04-10 560 views
0

我想下面的SVG字符串轉換爲圖像與JS:SVG圖像轉換麻煩

<svg xmlns:ct="http://gionkunz.github.com/chartist-js/ct" width="100%" height="100%" class="ct-chart-line" id="test-chart" style="width: 100%; height: 100%;"><g class="ct-grids"><line y1="165" y2="165" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line><line y1="115" y2="115" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line><line y1="65" y2="65" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line><line y1="15" y2="15" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line></g><g><g series-name="performance" class="ct-series ct-series-a"><path d="M50,165C53.57,165,403.415,155,406.984,155" class="ct-line"></path></g><g series-name="bemchmark" class="ct-series ct-series-b"><path d="M50,165C53.57,165,403.415,45,406.984,45" class="ct-line"></path></g></g><g class="ct-labels"><foreignObject style="overflow: visible;" x="40" y="170" width="356.984375" height="20"><span class="lineChartLabel ct-horizontal ct-end" style="width: 357px; height: 20px" xmlns="http://www.w3.org/2000/xmlns/">Jan</span></foreignObject><foreignObject style="overflow: visible;" x="396.984375" y="170" width="30" height="20"><span class="lineChartLabel ct-horizontal ct-end" style="width: 30px; height: 20px" xmlns="http://www.w3.org/2000/xmlns/">Feb</span></foreignObject><foreignObject style="overflow: visible;" y="115" x="10" height="50" width="30"><span class="lineChartLabel ct-vertical ct-start" style="height: 50px; width: 30px" xmlns="http://www.w3.org/2000/xmlns/">0%</span></foreignObject><foreignObject style="overflow: visible;" y="65" x="10" height="50" width="30"><span class="lineChartLabel ct-vertical ct-start" style="height: 50px; width: 30px" xmlns="http://www.w3.org/2000/xmlns/">0.5%</span></foreignObject><foreignObject style="overflow: visible;" y="15" x="10" height="50" width="30"><span class="lineChartLabel ct-vertical ct-start" style="height: 50px; width: 30px" xmlns="http://www.w3.org/2000/xmlns/">1%</span></foreignObject><foreignObject style="overflow: visible;" y="-15" x="10" height="30" width="30"><span class="lineChartLabel ct-vertical ct-start" style="height: 30px; width: 30px" xmlns="http://www.w3.org/2000/xmlns/">1.5%</span></foreignObject></g></svg> 

我什麼都試過了我能找到,像simg.js或這個腳本,例如:

var svg = document.getElementById('test-chart'), 
xml = new XMLSerializer().serializeToString(svg), 
data = "data:image/svg+xml;base64," + btoa(xml), 
img = new Image(); 
img.setAttribute('src', data) 
document.body.appendChild(img) 

但生成的圖像總是「破碎」,即根本沒有出現。使用更簡單的SVG字符串的腳本工作得很好。

我不明白我的字符串有什麼問題,它是由chartist.js生成的,並且在瀏覽器中很好地顯示,但似乎罪魁禍首是<foreignObject>元素,就像我刪除它們一樣,事情工作正常。

有沒有辦法將該SVG字符串轉換成JS圖像?

+0

也許相對寬度和高度是問題。你檢查過這個嗎? http://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-the-browser –

+0

如何使用畫布而不是xml。看看[this](http:// stackoverflow。com/questions/27230293/how-to-convert-svg-to-png-using-html5-canvas-javascript-jquery-and-save-on-serve) – Ghita

+0

@Ghita在繪製到畫布之前,必須先通過svg轉換成''標籤。看看你鏈接到的帖子;-) – Kaiido

回答

2

你的問題是xmlns屬性包含在<foreignObjects><span>元素設置是錯誤的。 目前它們被設置爲http://www.w3.org/2000/xmlns/,這是默認的XML名稱空間。它應該是http://www.w3.org/1999/xhtml,因爲包含的元素屬於xhtml命名空間。

我確實相信你沒有自己設置,而且你使用的庫是這樣做的。

你可以離開它的作者問題報告,但要注意IE < 11不支持這個<foreignObject>標籤,而目前的Safari瀏覽器有代表這樣的標籤(如果你想畫它放回<img>標籤的一些安全限制到一個畫布,它會污染這一個)。所以在我的個人意見仍然不建議使用這個標籤。

還要注意的是,因爲有人說,你必須設置絕對widthheight屬性根<svg>所以在<img>標籤顯示正確。

最後,你不需要base64對你的字符串進行編碼,而012URdataURI頭是從IE9到Edge的所有瀏覽器都支持的唯一的頭。

這裏是你的標記應該如何看起來像:

var svgData = (new XMLSerializer()).serializeToString(test) 
 
var dataURI = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData); 
 
var img = new Image(); 
 
img.src = dataURI; 
 
document.body.appendChild(img);
<h3> 
 
svg version 
 
</h3> 
 

 
<svg xmlns:ct="http://gionkunz.github.com/chartist-js/ct" width="500" height="200" class="ct-chart-line" id="test" style="width: 100%; height: 100%;"> 
 
    <g class="ct-grids"> 
 
    <line y1="165" y2="165" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line> 
 
    <line y1="115" y2="115" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line> 
 
    <line y1="65" y2="65" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line> 
 
    <line y1="15" y2="15" x1="50" x2="406.984375" class="ct-grid ct-vertical"></line> 
 
    </g> 
 
    <g> 
 
    <g series-name="performance" class="ct-series ct-series-a"> 
 
     <path d="M50,165C53.57,165,403.415,155,406.984,155" class="ct-line"></path> 
 
    </g> 
 
    <g series-name="bemchmark" class="ct-series ct-series-b"> 
 
     <path d="M50,165C53.57,165,403.415,45,406.984,45" class="ct-line"></path> 
 
    </g> 
 
    </g> 
 
    <g class="ct-labels"> 
 
    <foreignObject style="overflow: visible;" x="40" y="170" width="356.984375" height="20" requiredExtensions="http://www.w3.org/1999/xhtml"><span class="lineChartLabel ct-horizontal ct-end" style="width: 357px; height: 20px" xmlns="http://www.w3.org/1999/xhtml">Jan</span></foreignObject> 
 
    <foreignObject style="overflow: visible;" x="396.984375" 
 
    y="170" width="30" height="20"><span class="lineChartLabel ct-horizontal ct-end" style="width: 30px; height: 20px" xmlns="http://www.w3.org/1999/xhtml">Feb</span></foreignObject> 
 
    <foreignObject style="overflow: visible;" y="115" x="10" height="50" width="30" ><span class="lineChartLabel ct-vertical ct-start" style="height: 50px; width: 30px" xmlns="http://www.w3.org/1999/xhtml">0%</span></foreignObject> 
 
    <foreignObject style="overflow: visible;" y="65" x="10" height="50" width="30" ><span class="lineChartLabel ct-vertical ct-start" style="height: 50px; width: 30px" xmlns="http://www.w3.org/1999/xhtml">0.5%</span></foreignObject> 
 
    <foreignObject style="overflow: visible;" y="15" x="10" height="50" width="30" ><span class="lineChartLabel ct-vertical ct-start" style="height: 50px; width: 30px" xmlns="http://www.w3.org/1999/xhtml">1%</span></foreignObject> 
 
    <foreignObject style="overflow: visible;" y="-15" x="10" height="30" width="30" ><span class="lineChartLabel ct-vertical ct-start" style="height: 30px; width: 30px" xmlns="http://www.w3.org/1999/xhtml">1.5%</span></foreignObject> 
 
    </g> 
 
</svg> 
 
<h3> 
 
img version 
 
</h3>

因此,如果您不能前解決這個問題,你必須遍歷包含到所有的HTML元素<foreignObject>元素和手動修復(HTMLelem.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')

+0

我一直在嘗試修改上面的代碼來生成PNG圖片。再一次,我嘗試了所有我能找到的東西,但沒有用這個經過修正的SVG字符串和PhantomJS!有任何想法嗎? – chris

-1

你可以用布JS: http://fabricjs.com/

var addShape = function(shapeName) { 

fabric.loadSVGFromURL('../assets/' + shapeName + '.svg', function(objects, options) { 
    var loadedObject = fabric.util.groupSVGElements(objects, options); 
    loadedObject.set({ 
    left: 0, 
    top:0, 
    angle:0 
    }).setCoords(); 
    canvas.add(loadedObject); 
    window.open(canvas.toDataURL('png')); 
    }); 
};