将 SVG 转换为 PNG 图像
Convert SVG to image in PNG
我正在使用 html2canvas 和 canvg 插件将 angular nvd3 图表转换为 svg,但是当我将饼图转换为 png 时,我看起来与图表相同,但是当我转换折线图或面积图时,其背景变为黑色和一些圆圈淹没在图像上。
我的密码是
var svgElements = $("#container").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function () {
var canvas, xml;
// canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
$.each($(this).find('[style*=em]'), function (index, el) {
$(this).css('font-size', getStyle(el, 'font-size'));
});
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
////this.className = "tempHide";
$(this).attr('class', 'tempHide');
$(this).hide();
});
html2canvas($("#container"), {
onrendered: function (canvas) {
var a = document.createElement("a");
a.download = "Dashboard.png";
a.href = canvas.toDataURL("image/png");
a.click();
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm','a4');
var width = doc.internal.pageSize.width;
var height = doc.internal.pageSize.height;
doc.addImage(imgData, 'PNG', 0, 0, width, height);
doc.save('Dashboard.pdf');
}
});
$("#container").find('.screenShotTempCanvas').remove();
$("#container").find('.tempHide').show().removeClass('tempHide');
大家帮帮我。
提前致谢
您的 svg 元素正在使用外部样式sheet nv.d3.min.css 设置样式。
canvg 似乎无法访问外部样式 sheets,因此您需要将其直接附加到您的 svg 节点中。
要做到这一点,如果您的样式 sheet 托管在与您的脚本相同的域中,您可以这样做:
var sheets = document.styleSheets;
var styleStr = '';
Array.prototype.forEach.call(sheets, function(sheet){
try{ // we need a try-catch block for external stylesheets that could be there...
styleStr += Array.prototype.reduce.call(sheet.cssRules, function(a, b){
return a + b.cssText; // just concatenate all our cssRules' text
}, "");
}
catch(e){console.log(e);}
});
// create our svg nodes that will hold all these rules
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
style.innerHTML = styleStr;
defs.appendChild(style);
// now append it in your svg node
thesvg[0].insertBefore(defs, thesvg[0].firstElementChild);
所以现在您可以调用 XMLSerializer,canvg 会很高兴。
(请注意,这不仅是 canvg 的限制,同样适用于在 canvas 上绘制 svg 的所有方法)。
Forked plunkr,我将 nv.d3.min.css 的内容复制到 同源 style.css.
谈话已经很晚了,但我只想补充一点,Kaiido 描述的解决方案,简单地说,就是将样式直接嵌入到 SVG 文档中。
为此,您操作 DOM 使 SVG 元素看起来像这样:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1">
<defs>
<style>
.rectangleStyle{
width:200px;
height:100px;
stroke:black;
stroke-width: 6;
fill: green;
}
</style>
</defs>
<rect class="rectangleStyle"/>
</svg>
我正在使用 html2canvas 和 canvg 插件将 angular nvd3 图表转换为 svg,但是当我将饼图转换为 png 时,我看起来与图表相同,但是当我转换折线图或面积图时,其背景变为黑色和一些圆圈淹没在图像上。 我的密码是
var svgElements = $("#container").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function () {
var canvas, xml;
// canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
$.each($(this).find('[style*=em]'), function (index, el) {
$(this).css('font-size', getStyle(el, 'font-size'));
});
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
////this.className = "tempHide";
$(this).attr('class', 'tempHide');
$(this).hide();
});
html2canvas($("#container"), {
onrendered: function (canvas) {
var a = document.createElement("a");
a.download = "Dashboard.png";
a.href = canvas.toDataURL("image/png");
a.click();
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm','a4');
var width = doc.internal.pageSize.width;
var height = doc.internal.pageSize.height;
doc.addImage(imgData, 'PNG', 0, 0, width, height);
doc.save('Dashboard.pdf');
}
});
$("#container").find('.screenShotTempCanvas').remove();
$("#container").find('.tempHide').show().removeClass('tempHide');
大家帮帮我。 提前致谢
您的 svg 元素正在使用外部样式sheet nv.d3.min.css 设置样式。
canvg 似乎无法访问外部样式 sheets,因此您需要将其直接附加到您的 svg 节点中。
要做到这一点,如果您的样式 sheet 托管在与您的脚本相同的域中,您可以这样做:
var sheets = document.styleSheets;
var styleStr = '';
Array.prototype.forEach.call(sheets, function(sheet){
try{ // we need a try-catch block for external stylesheets that could be there...
styleStr += Array.prototype.reduce.call(sheet.cssRules, function(a, b){
return a + b.cssText; // just concatenate all our cssRules' text
}, "");
}
catch(e){console.log(e);}
});
// create our svg nodes that will hold all these rules
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
style.innerHTML = styleStr;
defs.appendChild(style);
// now append it in your svg node
thesvg[0].insertBefore(defs, thesvg[0].firstElementChild);
所以现在您可以调用 XMLSerializer,canvg 会很高兴。
(请注意,这不仅是 canvg 的限制,同样适用于在 canvas 上绘制 svg 的所有方法)。
Forked plunkr,我将 nv.d3.min.css 的内容复制到 同源 style.css.
谈话已经很晚了,但我只想补充一点,Kaiido 描述的解决方案,简单地说,就是将样式直接嵌入到 SVG 文档中。
为此,您操作 DOM 使 SVG 元素看起来像这样:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1">
<defs>
<style>
.rectangleStyle{
width:200px;
height:100px;
stroke:black;
stroke-width: 6;
fill: green;
}
</style>
</defs>
<rect class="rectangleStyle"/>
</svg>