我可以将 SVG 文本转换为路径但重用字形吗?

平面设计 墨景 svg
2022-01-24 01:37:08

我有一个带有大量文本的 SVG。这是一张停车场地图,上面写着车位号。我在网络浏览器中显示它,并且由于Firefox 中的一个奇妙的小错误,浏览器会错误地呈现文本。嘘。

所以我将文本转换为路径。我们谈论的是多达 4000 个单独的标签。现在可能有 15,000 个新形状它们是矢量。它是 4MB。通常,您可能会争辩说这有助于压缩,但必须将此 SVG 内联到 HTML中。我正在动态添加 CSS 更改,这是我有机会获得跨浏览器支持的唯一方法。所以无论如何,这个原始的——甚至是经过打磨的——输出太大而没有用处。

令我印象深刻的是所有这些空格数字共享共同的字形。零到九。为什么我要为每个数字的每个实例都包含一个形状定义?我可以对这些进行重复数据删除吗?

我正在使用 Inkscape,但我愿意接受建议。

4个回答

<use>元素允许您重用文档中其他地方定义的对象。例如,您可以将每个字形定义为 a <symbol>,然后多次重复使用它们。这是一篇关于它的好文章:SVG 中的结构化、分组和引用 - The <g>, <use>, <defs>and <symbol>Elements

不过,我不知道如何直接在 Inkscape 中执行此操作——尤其是对于您已经拥有的一堆文本。您可能必须编写一个脚本来对 SVG 进行后处理并找到所有可以重用的路径。

有一些可用的压缩选项可以提供不同程度的成功。为了测试它们,我创建了一个仅包含大量重复文本的图稿文件。未展开时,文件大小为 13.8 KB。展开后,文件大小为1.42 MB

不错的选择:使用 SVGZ - 46.5 KB

将展开的图稿保存为 SVGZ 给了我一个 46.5 KB 的输出文件,它比标准 SVG 小得多。请注意,虽然支持可能会有所不同

更好的选择:用 Scur 压缩 - 21.1 KB

Scur是一个可以为您清理和优化 SVG 文件的工具。使用 的“最大压缩”命令scour -i input.svg -o output.svgz --enable-viewboxing --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=none,展开后的图稿减少到 21.1 KB。与原始未扩展的文件大小相差不远!

这是浏览器内或服务器上的解决方案

有许多不同的方法可以优化 SVG 文件。听起来你已经做了很多。

我发现一些非常有用的资源是一篇css-tricks 文章,它专注于非常具体的细节。特别是它使用SVGO的工具。

如果您有许多重复的路径,我会考虑使用 javascript 动态创建形状。这里有一个例子一个方向是为每个字形定义一个函数,并简单地将每个路径包含在由对该函数的请求创建的 svg 元素中。或者采用完整的字符串和/或参数数组来创建您的内联 svg。当然,这期望您的路径比请求所述功能所需的代码长度更长(很容易假设)。

在一个非常高的层次上是你的脚本应该做的。随意使用您喜欢的语言和环境,这只是一个逻辑的起点,它应该为您提供您正在寻找的东西。

  • 循环遍历 SVG 的 xml 中的所有文本元素,对于那些具有数字文本的元素(停车位,您不指定 svg 中是否有更多文本),将 Inkscape 自动创建的 id 更改为具有该停车位的字符串现货的编号。Inkscape 只需要唯一的 ID,它会生成非描述性 ID,但会尊重且不会更改由其他软件创建或由用户手动创建或更改的 ID。
  • 在表格中存储每个停车位的文本元素的 x 和 y 坐标。
  • 无论是在 Inkscape 中还是通过脚本,将所有停车位文本转换为路径。
  • 对于数字 0-9 附加到 SVG 文件的适当<defs>部分定义每个数字的路径信息。
  • 循环遍历所有的<g>停车位并将它们替换为<use xlink:href="#digit" x=x y=y />
  • 利润

我可以预见到一些你将不得不处理的复杂情况,祝你好运。

  • 循环需要用 2 位或更多位数分割停车位字符串,并且第一个数字和后续数字之间的适当间距可能很棘手;这在很大程度上取决于您使用的字体。
  • 您没有指定停车位的方向,或者它们是否在弯曲的设置上。由于 2 位数字或更大数字的手动 x、y 偏移,您可能需要额外的逻辑来确定停车位的“方向”以及如何正确地将单个数字的不同路径与第一个数字隔开。

希望这可以帮助。祝你好运。