将svg转换为png时如何包含CSS样式

我创建了一个简单的SVG元素,单击按钮时将其下载到png,我的解决方案与此类似

基本思想是:

1.svg到画布

2.canvas到dataUrl

3.trigger从dataUrl下载

喜欢这里或通过下挖DOM树,并使用递归解决方案

问题:

(是否与GPU加速相关?)2.在

 <button id="btn">svg to png</button>

<svg id="svg" width="200" height="200">

<circle cx="50" cy="50" r="30" />

<text class="svgTxt" x="0" y="100">Hen's SVG Image</text>

</svg>

<canvas id="canvas" width="200" height="200"></canvas>

我的CSS:

  /*adding exo2 font*/

@font-face {

font-family: 'exo_2black';

src: url('./exo2font/Exo2-Black-webfont.eot');

src: url('./exo2font/Exo2-Black-webfont.eot?#iefix') format('embedded-opentype'),

url('./exo2font/Exo2-Black-webfont.woff') format('woff'),

url('./exo2font/Exo2-Black-webfont.ttf') format('truetype'),

url('./exo2font/Exo2-Black-webfont.svg#exo_2black') format('svg');

font-weight: normal;

font-style: normal;

}

/*change circle color depends on window size*/

@media screen and (min-width: 480px) {

svg circle {

fill: lightgreen;

}

}

/*style on the svg text*/

.svgTxt{

font-family: 'exo_2black';

font-size: 30px;

fill: red;

}

我的代码:

  //reference to elements

var btn = document.querySelector('#btn');

var svg = document.getElementById('svg');

var svgTexts = svg.getElementsByTagName('text');

var canvas = document.getElementById('canvas');

//Style definitions for svg elements defined in stylesheets are not applied to the generated canvas. This can be patched by adding style definitions to the svg elements before calling canvg.

//3.trigger download from dataUrl

function triggerDownload(imgURI) {

var evt = new MouseEvent('click', {

view: window,

bubbles: false,

cancelable: true

});

var a = document.createElement('a');

a.setAttribute('download', 'hen_saved_image.png');

a.setAttribute('href', imgURI);

a.setAttribute('target', '_blank');

a.dispatchEvent(evt);

}

//btn click event

btn.addEventListener('click', function () {

// 1.svg to canvas

var ctx = canvas.getContext('2d');

var data = (new XMLSerializer()).serializeToString(svg);//serialize the svg element to string

var DOMURL = window.URL || window.webkitURL || window;

var img = new Image();

var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });//A blob object represents a chuck of bytes that holds data of a file.

var url = DOMURL.createObjectURL(svgBlob);//creates a DOMString containing an URL representing the object given in paramete

$('svg').append(deletedSVGText);

img.onload = function () {

ctx.drawImage(img, 0, 0);

DOMURL.revokeObjectURL(url);

// 2.canvas to dataUrl

var imgURI = canvas

.toDataURL('image/png')

.replace('image/png', 'image/octet-stream');// returns a data URI containing a representation of the image in the format specified by the type parameter

triggerDownload(imgURI);

};

img.src = url;

});

回答:

真正的原因 是什么(无论如何,GPU加速是否相关?)

不,GPU加速与它无关。

最广泛的原因是 。

要绘制svg,drawImage您必须将svg作为外部文档加载到<img>标签内。SVG可能是用于加载资源的非常复杂的图像格式(它实际上可能需要任何HTML文档可能需要的任何类型的资源)。因此,已在规范中指出,与<iframe>元素<object>或类似元素相同的安全性应适用于<img>内容,甚至更为严格:

<img> 内容可以不需要任何外部资源,也不需要访问主文档。

以及此问题的解决方案

您指出了一些已经回答过的SO问题,也可以在从中<style>创建Blob之前,仅将主文档中的所有样式表包括在已解析的svg Node内的标签内

“在Fontface中使用自定义字体时,如何仍能解决此问题”

对于外部资源,您必须将其编码为dataURI,并在创建Blob之前将其包括在svg节点中。特别是对于字体,您需要font-

face在一个<style>元素中设置一个属性。

因此,最后,您的svg会有类似

<defs>

<style>

/* all your parsed styles in here */

@font-face {

font-family: foo;

src: url('data:application/font-woff;charset=utf-8;base64,...')

}

</style>

</defs>

本身,然后再提取其标记。

以上是 将svg转换为png时如何包含CSS样式 的全部内容, 来源链接: utcz.com/qa/424656.html

回到顶部