如何在保留图层的同时将 SVG 转换为 PNG?
Posted
技术标签:
【中文标题】如何在保留图层的同时将 SVG 转换为 PNG?【英文标题】:How to convert SVG to PNG while still preserving the layers? 【发布时间】:2021-09-09 17:19:48 【问题描述】:我的 SVG 图像如下所示:
这是该 SVG 文件的摘录:
<g id="surface1">
<g clip-path="url(#clip1)" clip-rule="nonzero">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 0.140625 0 L 1683.609375 0 L 1683.609375 2390.601562 L 0.140625 2390.601562 Z M 0.140625 0 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 0.140625 0 L 1683.609375 0 L 1683.609375 2383.855469 L 0.140625 2383.855469 Z M 0.140625 0 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(93.728638%,93.328857%,91.369629%);fill-opacity:1;" d="M 0.140625 0 L 1683.609375 0 L 1683.609375 2383.855469 L 0.140625 2383.855469 Z M 0.140625 0 "/>
</g>
<g clip-path="url(#clip2)" clip-rule="nonzero">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.879517%,85.879517%,85.879517%);fill-opacity:1;" d="M 196.179688 546.039062 C 185.273438 546.039062 176.347656 554.964844 176.347656 565.871094 C 176.347656 565.871094 176.347656 566.121094 176.347656 566.121094 C 177.339844 649.417969 181.304688 977.402344 176.101562 1277.371094 C 169.902344 1624.445312 207.089844 1785.585938 207.089844 1785.585938 L 1341.292969 1785.585938 C 1341.292969 1785.585938 1390.875 1438.511719 1378.476562 1172.011719 C 1366.082031 905.507812 1378.476562 713.378906 1335.09375 632.808594 C 1291.707031 552.238281 764.894531 558.4375 609.949219 552.238281 C 480.042969 547.03125 263.117188 546.289062 196.179688 546.039062 Z M 196.179688 546.039062 "/>
</g>
<g clip-path="url(#clip3)" clip-rule="nonzero">
<g clip-path="url(#clip4)" clip-rule="nonzero">
<g clip-path="url(#clip5)" clip-rule="nonzero">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(73.329163%,42.349243%,17.248535%);fill-opacity:1;" d="M 407.738281 1958.871094 C 400.707031 1854.550781 467.722656 1826.082031 498.4375 1760.117188 C 529.148438 1694.152344 714.296875 1454.164062 1021.128906 1471.179688 C 1327.957031 1488.195312 1477.898438 1544.210938 1492.515625 1710.101562 C 1507.136719 1875.992188 1435.222656 2096.339844 1287.71875 2121.804688 C 1140.21875 2147.269531 707.75 2176.964844 636.011719 2178.085938 C 484.5 2180.882812 412.949219 2036.085938 407.738281 1958.871094 Z M 407.738281 1958.871094 "/>
</g>
</g>
</g>
...
</g>
我想知道是否有一个已知的解决方案如何将此 SVG 转换为仅由 PNG Base64 字符串组成的 SVG,其中每个图层中的对象和图层本身都被保留。因此,相对于当前的 SVG 文件只包含 <g>
和 <path>
标签,我想将此 SVG 转换为只包含 <image>
标签的 SVG 文件,其中图像数据包含在 @ 987654327@ 属性,像这样:
<image id="Lager_1" data-name="Lager 1" width="185.9" height="244.95000000000002" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALkAAAD ...
我已经连续 2 周寻找这个问题的解决方案了,所以任何帮助都将不胜感激。对于那些会问“你确定要这样做吗?”的人。答案是是的。
我目前最好的猜测是在 javascript 画布上一一加载图层并将它们一一转换为 PNG,然后将标签完全替换为生成的图像字符串。
【问题讨论】:
你的最佳猜测对我来说听起来是个好主意......你有什么问题吗? 我想知道这个用例是什么。请注意,您可以将 CSS 样式应用于<g>
元素,如 style="display: none;"
。可能会让您的想法更容易处理。
目前在做,虽然目前遇到很多问题和bug,但应该是可以的。
感谢Ouroborus,放心,这个问题的解决方案有真实的用例。
究竟是什么用例?作为该领域的“专家”,我没有看到任何一个用例可以有益于这样做。如果您想提高绘制该图像的性能,因为您听说位图渲染比矢量更快,这不会,1. 您的矢量很简单,2. 矢量引擎仍然必须启动,3. 多个光栅将需要解析。总而言之,这里的一切都是值得的,从大小到内存使用,再到解码和光栅化时间。
【参考方案1】:
像 cmets 中的许多人一样,我也对此用例感兴趣,我看不到任何好处。
还有你的:
只是有点难以处理所有特殊情况 关于如何定义 SVG 中的属性, 大量的解析。
让我对为什么、如何和什么更加好奇strong> 你在做。
只有解析应该由浏览器完成。 程序流程不应超过:
对所有 SVG 层重复 克隆原始 SVG https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode 删除您不想要的图层 https://developer.mozilla.org/en-US/docs/Web/API/Element/remove 将 克隆 SVG 使用 Canvas 转换为二进制图像 循环所有克隆的图像 替换 原始 SVG 中的图层为<image>
您还没有回答所有问题为什么您想要二进制文件。
如果你想要一个 SVG <image>
标签(出于某种原因)
您还可以使用以下方式对分层 SVG 进行 dataURI:
function svg2img()
let svg = document.querySelector('svg');
let xml = new XMLSerializer().serializeToString(svg);
let svg64 = btoa(xml); //for utf8: btoa(unescape(encodeURIComponent(xml)))
return 'data:image/svg+xml;base64,' + svg64;
;
免责声明:我从博客中复制了代码 sn-p;没有测试代码
【讨论】:
与其删除所有不想要的,更安全的解决方案是通过style
属性隐藏它们,删除可能会改变 CSS 选择器。
但与 html 不同的是,在 SVG 中 <style></style>
优先于 style
属性。所以你不能确定style="display:none"
实际上隐藏了元素。移除 <g>
、 <path>
等 SVG 元素不会影响任何“全局”css;除非它们本身包含 <style>
定义。
不,style
的工作方式与 HTML 相同。您可能对 fill
等表示属性的 CSS 等价物感到困惑。是的,删除元素会改变所有规则,如 nth-child()
或 elem ~ elem
等。以上是关于如何在保留图层的同时将 SVG 转换为 PNG?的主要内容,如果未能解决你的问题,请参考以下文章
如何在ghostscript中将svg、eps和ai转换为png