gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 09:24:09 25 4
gpt4 key购买 nike

我创建了一个简单的 SVG 元素,当点击一个按钮时它会下载到 png,我的解决方案类似于 here


基本思路是:
1.svg转 Canvas
2.canvas转dataUrl
3.从dataUrl触发下载

问题是在下载 png 文件时,它不包含应用于 svg 的 css 样式 my solution result

注意 - 我知道有一个变通解决方案,可以通过在元素上“内联”移动样式,例如 here或通过挖掘 DOM 树并使用 getComputedStyle(element,null); 的递归解决方案

问题:
1.此问题的真正原因和解决方案是什么。
(无论如何与GPU加速相关?)
2.当使用带有 Fontface 的自定义字体时,我如何仍然克服这个问题

 <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;
});

最佳答案

问题 1(前半部分): 真正的原因是什么(GPU 加速是否相关?)

不,GPU加速与它无关。
最广泛的原因是隐私

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

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

问题 1(后半部分):以及此问题的解决方案

您指出了一些已经回答了它的 SO 问题,您也可以将主文档中的所有样式表包含在 <style> 中。在你从它创建 Blob 之前,在你解析的 svg 节点中标记。 dumb implementation here

问题 2: “在使用带有 Fontface 的自定义字体时,我如何解决这个问题”

对于外部资源,您必须将其编码为 dataURI,并在创建 Blob 之前将其包含在您的 svg 节点中。特别是对于字体,您将设置 font-face <style> 中的属性(property)元素。

所以最后,你的 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>

在提取其标记之前本身。

关于css - 将 svg 转换为 png 时如何包含 CSS 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41571622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com