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


14

我有一个SVG,上面有很多文字。这是一个停车场地图,上面写有空间编号。我将其显示在网络浏览器中,这要归功于Firefox中的一个出色的小错误,该浏览器无法正确显示文本。嘘

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

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

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


您是否有可能共享SVG文件,以便我们进行实验?
JohnB

1
到底是什么错误(截图),以及如何将其导出并加载到浏览器?您很有可能仅通过一些CSS样式或页面上的小脚本来修复/替换文本元素即可对其进行修复。如果这是动态地图显示,则可能需要将其转换为实际地图-大多数浏览器映射库(以及许多基于数据的库)都对标签提供了强大的支持。
brichins

1
抱歉,SVG不是我的共享对象(它属于客户端),但有关bug的信息是已知的。从本质上讲,这意味着SVG中的字体不会缩小到一个点以上……如果在具有成千上万个已编号停车位的地图上一路放大,这将是一个严重的问题。它们应该是(例如)〜0.08pt,实际上是13pt。
奥利

1
你有错误的bug数量,你实际上是在寻找这一个
罗伯特Longson

您可能要在一个子集上进行测试,但是可以path|simplify帮助您吗?小写的“ s”将转换为28点路径,将其简化为17,并覆盖甚至缩放后的简化和未简化版本,因此一个“ s”将填满整个屏幕。
克里斯·H

Answers:


6

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

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


<use>是我在想,如果我问这个,脚本是怎么样。似乎没有办法消除重复几乎相同的标记,这似乎很愚蠢。
奥利

@Oli甚至都没有删除相同的标记;我必须编写自己的文件(同样,我的意思是对字节;我对它们进行散列并比较散列)
Chris H

我在午餐时考虑了一下,对我来说,像inkscape中的(python)脚本将是一种方法。该脚本将以文本作为文本开头,并替换为对<symbol>s的引用(或者看起来您可以使用<def>文本到路径的字形
Chris H

4

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

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

将扩展的图稿另存为SVGZ,可以得到46.5 KB的输出文件,该文件明显小于标准SVG。请注意,尽管支持可能会有所不同

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

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


3
精练不会压缩,它只是消除了垃圾,尽管确实对我有很多好处(考虑到大量的对象),但我的“ 4MB”是后期精练的。压缩的内容会很棒,但是-我应该在前面提到过-我必须内联SVG以解决浏览器定位问题(以及前端操纵要求)。我知道,我知道,这很痛苦,但是当我说现在对我伤害更大的时候,请相信我D:
Oli 2016年

我应该说,的精练部分scour不会压缩。它可以通过gzip的你,但ID和空白微小的东西是它的主要演出扔文件。
奥利

@Oli对,因此我对“ optimize”一词的谨慎选择:)真可惜,您的文件已经被Scoured了,但是... ack!
JohnB

我在Illustrator中弄乱了一些;它的SVG输出确实遵守Symbols。这是一个简单的例子。这会花费很多精力,但是您可以创建一个Illustrator脚本,该脚本会将您的文本分解为单个字符,然后将它们替换为Symbols。我看到的最大障碍是应对轮换。如果所有文本都与X轴平行,这似乎并不困难,但是以一定角度处理文本可能是一个挑战。当然,如果您没有Illustrator,那么所有这些都不会很有帮助
JohnB

3

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

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

我发现一些有用的资源是css-tricks文章,该文章侧重于非常具体的细节。具体来说,该工具使用SVGO

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


1
尽管此答案提出了多种可能的解决方案,但SVGO似乎最有趣。它也可以在.svg文件上运行以对其进行优化。但是,它目前似乎并未进行路径重复数据删除。如果询问者最终还是执行自定义脚本,那么将其作为对SVGO的增强可能是个好主意。
jpa

当然,在转换为路径之前(或同时)进行@jpa重复数据删除是一种方法。替换文本字符“1”的所有实例 <use xlink:href="#digit_one">,其中digit_one是路径
克里斯^ h

@ChrisH我不明白为什么以后也不能重复删除。只需将起点的所有路径归一化,进行哈希处理,然后使用该值来查找路径是否已经发生。当然,不是那么优雅,但是应该有效,并且比重新实现/弄清所有文本布局逻辑更容易实现。
jpa

@jpa可以,但是如果标准化原点会导致舍入错误,则哈希将不匹配。我正在考虑的脚本将调用inkscape的“文本到路径”来布局字符路径,然后用对一组母版的引用替换它们。
克里斯·H

@jpa和舍入错误是真实的。在一个玩具示例中,零的第一个二次曲线在小数点后第六位相差1 —足以搞乱哈希
克里斯ħ

2

这里是您脚本应该做什么的一个很高的层次。随意使用您喜欢的语言和环境,这只是逻辑的起点,该逻辑应该可以为您提供所需的内容。

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

我可以预见您将要处理的一些并发症,并祝他们好运。

  • 该循环将需要用2位或更多位数来拆分停车位字符串,并且第一位数字与后续数字之间的适当间距可能会比较棘手;这将在很大程度上取决于您使用的字体。
  • 您不指定停车位的方向,也不指定停车位是否弯曲。由于2个数字或更大数字的手动x,y偏移量,您可能需要其他逻辑来找出停车位的“方向”,以及如何正确地将各个数字的不同路径与第一个数字隔开。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.