是否可以将SVG的文件大小减小到更接近JPEG的大小?


37

我有一个正在网站上使用的图片。我想使用SVG,以便它可以是任何大小,并且看起来仍然清晰。

  • 此保管箱包含SVG文件以及原始Illustrator文件。
  • 这是JPEG导出:

    JPEG导出

SVG的文件大小比JPG大。是否可以优化SVG,使其具有相似的文件大小?如果有帮助,我可能会失去一些品质。我已经尝试过这个SVG优化器,但是并没有太大的区别。

如果我将插画器文件另存为JPG,跟踪结果并将其另存为SVG,则文件大小会小得多,但质量会有所下降。这使我认为可能是原稿中的图层导致了较大的尺寸?我正在处理的图像是否太复杂而无法适合SVG?


16
与您的问题无关,但您不应将JPG用于此类图片。相反,请使用PNG:大小可能会相似,并且不会损失任何质量。
svick

一定要意识到,比较将取决于图像的物理尺寸。缩放JPEG会大大增加尺寸。缩放SVG无效。可以想象一个很小的图标会比JPEG还要小,尽管我不会说您的图形很小。
Paul Draper 2015年

如果您不是Inkscape用户,并且对手动打高尔夫球SVG并不自信,那么您可能会喜欢我在答案中链接到的在线工具。
Dom

1
只是为了补充svick的评论:PNG更好的“像这样”的图像是具有透明边缘的任何东西或具有彩色或白色的清晰实心区域的任何东西。如果它是“图形”(例如徽标,图标等)而不是“照片”,则PNG通常更好。JPG更适合照片(或逼真的图像)。
user56reinstatemonica8

Answers:


40

SVG在控制器的右下角包含一个用于阴影的嵌入式像素图形。这大约占文件大小的1/3。如果删除它,则SVG文件与JPEG相同。您可能可以通过渐变获得足够类似的效果。

其他减小SVG文件大小的技术包括:

  • 删除所有元数据和类似内容。Inkscape 为此具有“ 另存为普通SVG ”。我想其他程序也有类似的东西。
  • 删除几乎不增加形状的节点,例如,控制器形状上存在虚假节点。

这使我认为可能是原稿中的图层导致了较大的尺寸?

除非您使用的层数过多(每个对象都想用一层),否则层数不应对文件大小产生重大影响,即使那样,它也只是一小部分。

我正在处理的图像是否太复杂而无法适合SVG?

如果您可以合理地从头开始创建图像¹,那么对于SVG格式来说,它应该不会太复杂。没有神奇的复杂性阈值可以超过文件大小(对于任何模糊合理的格式都适用)。当然,如果只选择足够粗糙的分辨率,则可以将每个SVG导出为文件大小较小的JPEG。但这并不一定意味着您不应该使用SVG。


¹特别是没有追踪和类似内容。举一个极端的例子:如果您想使用SVG原语精确地复制照片的每个像素(即,不将像素图形嵌入SVG),则您可能确实认为结果太复杂而无法有效地以SVG格式表示。但这是常识。


80

正如Wrzlprmft所指出的那样,嵌入式PNG位图图像占用了SVG文件大小的50%以上,该图像用于在控制器上产生相当细微的阴影效果。仅仅去除该图像,并用简单的径向渐变替换它,就足以将SVG缩小到大约10kb。

        原版的         具有简单的径向渐变
原始图像在左侧带有花式位图阴影,在编辑版本中带有简单的径向渐变。

在进行此操作时,还应该检查路径,看看是否有任何要简化的地方。我没有发现太多,但是控制器的轮廓确实有一些相邻的节点(靠近顶部和底部中间),可以将它们合并而不会产生任何明显的区别。

那很容易节省50%的费用,但我们还不要停止。如果你知道,即使对一点点SVG格式,你可以做很多比这更好的。

首先,在Inkscape中运行“ Vacuum Defs”以摆脱无用的定义,然后将图像另存为“纯SVG”。现在,是时候在文本编辑器中打开它了,看看我们可以摆脱什么。理想情况下,您应该使用带有集成SVG预览的编辑器,以便可以快速查看您的编辑对图像外观有什么影响(希望没有)。我为此使用emacs,但还有其他具有类似功能的编辑器

无论如何,在文本编辑器中打开SVG文件后,让我们开始简化它!

  • 在顶部,有很多没用的东西<!-- comment -->。只需删除它。

  • 如果您是直接从Illustrator编辑SVG,则还有一条无用的<!DOCTYPE ... >行。也删除它。

  • Inkscape坚持将无用的RDF元数据块粘贴到图像中。只需找到<metadata ...>标签并删除它,然后再删除所有内容,包括close即可</metadata>

  • 另外,即使将文件另存为“普通SVG”,Inkscape仍然会用一堆自定义属性来乱扔它。查找以inkscape:或开头的每个属性,sodipodi:然后将其删除。

  • 随着元数据和特定于Inkscape的属性消失,您可以从<svg>标记中删除所有未使用的XML名称空间属性。它应该是安全地删除至少xmlns:rdfxmlns:dcxmlns:ccxmlns:inkscapexmlns:sodipodi。如果有多余的xmlns:svg属性,也将其删除。此时,您仅需保留的名称空间属性是:

    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
  • <svg>标签还具有很多其他的没用的属性,你可以安全地删除,如enable-backgroundxml:space="preserve"。(那些由Illustrator的SVG出口插入,和Inkscape中是不够聪明,认识到他们是无用的。)该viewBox属性还可以安全地从这一形象删除,因为它只是重复的值xywidthheight属性。

  • 您还可以安全地从标记中删除encodingstandalone属性<?xml ... ?>

  • 现在让我们来了解图像数据的精髓。由于某些原因,Inkscape坚持id为每个元素分配属性,即使从未引用过它们也是如此。id可以在文件中的其他位置(其搜索内容!)重复使用其值永远不会重复的任何属性。基本上,您需要保留的唯一ID是渐变的ID,也可能是<defs>截面内找到的任何其他对象(例如,路径)的ID 。

  • 此外,Inkscape喜欢生成像这样的长ID linearGradient4277。考虑将您不能删除的所有ID缩写为类似的缩写lg1

  • 紧接着还有多个<defs>部分。合并它们可以节省一些字节(通常简化了文档结构)。

  • <g>文件末尾还有几个空组(元素)。只是摆脱他们。也可能有多个连续的组具有完全相同的transform属性(或完全没有属性);合并它们也是安全的。

  • 由于某些奇怪的原因,Inkscape d<circle>元素保存了冗余的Bezier路径(属性)。这绝对没有理由占用空间,因此只需删除它们即可。(将元素的d属性保留<path>为;这些属性实际上用于某物。)

  • Inkscape还喜欢style在更具体的属性会更短的属性中使用CSS ,例如重写fill="#4888fa"为更详细的属性style="fill:#4888fa"。您可以通过将这些样式分解为单独的属性(并删除那些无用地重复默认设置的样式)来节省一些字节,但是与上述大多数更改相比,它们对SVG格式的熟悉程度更高。

  • 另外,如果有任何<use ... >元素,则可以通过将它们替换为链接到的实际元素来节省一些字节。(当然,如果链接的元素仅使用一次,这只会节省空间。)似乎Inkscape喜欢间接定义圆形渐变,首先在a中定义停止点<linearGradient>,然后在<radialGradient>;中引用它们。您可以通过直接在径向渐变内移动光阑并摆脱现在未使用的线性渐变来简化此过程。另外,如果这样做可以消除所有xlink:href属性,则可以xmlns:xlink<svg>标记中删除该属性。

  • 如果您真的想挤出最后一个多余的字节,请查找带有太多小数位的数字值,并将其四舍五入为更合理的值。这是实时预览真正有用的地方,因为它可以让您看到在值开始可见之前可以舍入多少。但是,即使您不想仔细测试每个数字以查看可以四舍五入多少,也可以至少选择低垂度的水果,例如将1.0000859像素值四舍五入为just 1

  • 最后,清理文件中的缩进和空格。为了绝对减少字节数,您需要将所有内容放在一行上(或者至少将换行符放在属性前面,无论如何都需要空格),但这确实很难阅读。不过,仍可以通过一些简单的,保守的缩进在可读性和紧凑性之间取得不错的平衡。

无论如何,这是我设法将SVG图像手动编辑为的内容:

<?xml version="1.0"?>
<svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  x="0" y="0" width="124" height="52">
<g transform="translate(1,-27.5)">
  <linearGradient id="lg1"
    x1="70.1063" y1="13.4122"
    x2="66.1994" y2="-26.4368"
    gradientUnits="userSpaceOnUse"
    gradientTransform="matrix(0.9997,-0.0263,0.0263,0.9997,-7.4,61.3)">
    <stop offset="0" stop-color="#154BBF" />
    <stop offset="1" stop-color="#6E8BFF" />
  </linearGradient>
  <path d="M 119.198,75.836 C 115.115,80.541 7.902,78.843 3.585,74.366 -0.734,69.888 -1.322,46.938 2.76,42.233 6.842,37.53 113.821,30.047 118.137,34.524 c 4.319,4.477 5.143,36.609 1.061,41.312 z" id="path3298" fill="url(#lg1)" />
  <linearGradient id="lg2"
    x1="70.4391" y1="13.5887"
    x2="70.4391" y2="-25.3265"
    gradientUnits="userSpaceOnUse"
    gradientTransform="matrix(0.9997,-0.0263,0.0263,0.9997,-7.4,61.3)">
    <stop offset="0" stop-color="#4166FA" />
    <stop offset="1" stop-color="#87A4FF" />
  </linearGradient>
  <path d="M 119.2,71.843 C 115.247,76.118 11.615,74.749 7.447,70.692 3.281,66.635 2.747,45.804 6.7,41.528 c 3.953,-4.277 107.372,-11.239 111.539,-7.183 4.167,4.057 4.915,33.222 0.961,37.498 z" id="path3305" fill="url(#lg2)" />
  <path stroke="#fff" stroke-width="5" d="m 103.734,64.225 0,0 c -0.921,-0.271 -1.661,-0.724 -2.2,-1.342 -0.917,-1.051 -0.957,-2.455 -0.88,-3.576 -1.831,-0.373 -3.866,-0.886 -7.099,-1.84 -3.233,-0.954 -5.221,-1.627 -6.961,-2.308 -0.544,0.983 -1.34,2.14 -2.679,2.525 -0.789,0.227 -1.656,0.204 -2.577,-0.068 -1.415,-0.417 -2.876,-1.431 -3.723,-2.583 -1.731,-2.354 -1.283,-6.55 -0.601,-9.655 0.964,-4.399 3.692,-11.662 7.252,-13.641 3.374,-1.877 12.426,0.468 16.37,1.6315 3.944,1.1635 12.873,4.1185 14.692,7.5355 1.914,3.596 0.262,11.176 -1.317,15.393 -1.113,2.978 -3.016,6.746 -5.746,7.782 -1.338,0.505 -3.117,0.564 -4.531,0.146 z" />
  <path fill="#4888fa" d="m 103.734,64.225 0,0 c -0.921,-0.271 -1.661,-0.724 -2.2,-1.342 -0.917,-1.051 -0.957,-2.455 -0.88,-3.576 -1.831,-0.373 -3.866,-0.886 -7.099,-1.84 -3.233,-0.954 -5.221,-1.627 -6.961,-2.308 -0.544,0.983 -1.34,2.14 -2.679,2.525 -0.789,0.227 -1.656,0.204 -2.577,-0.068 -1.415,-0.417 -2.876,-1.431 -3.723,-2.583 -1.731,-2.354 -1.283,-6.55 -0.601,-9.655 0.964,-4.399 3.692,-11.662 7.252,-13.641 3.374,-1.877 12.426,0.468 16.37,1.6315 3.944,1.1635 12.873,4.1185 14.692,7.5355 1.914,3.596 0.262,11.176 -1.317,15.393 -1.113,2.978 -3.016,6.746 -5.746,7.782 -1.338,0.505 -3.117,0.564 -4.531,0.146 z" />
  <path fill="#87b5ff" d="m 114.774,40.292 c -1.17,-2.151 -7.571,-4.939 -14.293,-6.921 V 33.37 c -0.023,-0.007 -0.047,-0.014 -0.07,-0.021 -0.023,-0.007 -0.047,-0.015 -0.071,-0.02 l 0,0 c -6.723,-1.985 -13.612,-3.12 -15.761,-1.949 -4.296,2.337 -9.198,17.315 -6.265,21.228 0.907,1.209 3.014,2.449 4.466,2.043 1.452,-0.404 2.121,-3.4 2.652,-3.174 2.518,1.077 5.601,2.117 8.744,3 3.119,0.966 6.272,1.765 8.972,2.229 0.569,0.097 -0.498,2.975 0.502,4.104 1.001,1.128 3.443,1.232 4.861,0.709 4.586,-1.693 8.602,-16.933 6.263,-21.227 z" />
  <path fill="#2f67c9" d="m 90.818,42.604 c -0.097,-0.194 -0.901,-0.575 -1.999,-1.006 0.317,-1.135 0.497,-2.007 0.401,-2.2 -0.319,-0.641 -3.681,-1.766 -4.323,-1.447 -0.192,0.096 -0.574,0.9 -1.004,1.998 -1.135,-0.315 -2.006,-0.497 -2.201,-0.401 -0.64,0.319 -1.766,3.681 -1.446,4.322 0.096,0.193 0.901,0.575 1.997,1.006 -0.316,1.134 -0.496,2.007 -0.4,2.199 0.32,0.64 3.682,1.767 4.323,1.447 0.193,-0.095 0.575,-0.901 1.005,-1.997 1.135,0.314 2.008,0.496 2.199,0.401 0.642,-0.32 1.767,-3.682 1.448,-4.322 z" />
  <path fill="#4888fa" d="m 100.282,33.311 c -0.024,-0.007 -0.046,-0.013 -0.069,-0.02 -0.023,-0.006 -0.046,-0.013 -0.07,-0.02 l 0,0 c -2.455,-0.725 -4.932,-1.334 -7.181,-1.755 -0.765,2.073 -1.164,4.497 -0.789,5.91 0.627,2.363 9.764,5.059 11.574,3.414 1.096,-0.996 2.091,-3.297 2.566,-5.483 -1.876,-0.731 -3.937,-1.428 -6.031,-2.046 l 0,0 z" />
  <circle fill="#639bff" r="3.427" cy="46.947" cx="101.382" />
  <circle fill="#4888fa" r="2.868" cy="45.940" cx="109.28" />
  <circle fill="#2f67c9" r="2.868" cy="52.538" cx="106.287" />
  <radialGradient id="rg3"
    cx="90.874" cy="39.29"
    fx="90.874" fy="39.29"
    r="19.89"
    gradientUnits="userSpaceOnUse"
    gradientTransform="matrix(1.7028,-0.3387,0.276,1.3872,-70.22,16.58)">
    <stop stop-color="#1166a8" stop-opacity="0" offset="0" />
    <stop stop-color="#1166a8" stop-opacity="0.02" offset="0.45" />
    <stop stop-color="#1166a8" stop-opacity="0.63" offset="1" />
  </radialGradient>
  <path d="m 103.734,64.225 0,0 c -0.921,-0.271 -1.661,-0.724 -2.2,-1.342 -0.917,-1.051 -0.957,-2.455 -0.88,-3.576 -1.831,-0.373 -3.866,-0.886 -5.973,-1.508 -0.375,-0.11 -0.75,-0.223 -1.124,-0.338 -0.378,-0.107 -0.753,-0.216 -1.128,-0.326 -2.107,-0.622 -4.095,-1.295 -5.835,-1.976 -0.544,0.983 -1.34,2.14 -2.679,2.525 -0.789,0.227 -1.656,0.204 -2.577,-0.068 -1.415,-0.417 -2.876,-1.431 -3.723,-2.583 -1.731,-2.354 -1.283,-6.55 -0.601,-9.655 0.964,-4.399 3.692,-11.662 7.252,-13.641 3.374,-1.877 12.426,0.468 16.245,1.591 l 0.274,0.081 c 3.795,1.123 12.724,4.078 14.543,7.495 1.914,3.596 0.262,11.176 -1.317,15.393 -1.113,2.978 -3.016,6.746 -5.746,7.782 -1.338,0.505 -3.117,0.564 -4.531,0.146 z" fill="url(#rg3)" />
</g></svg>

该SVG图像看上去与上面的第二个示例图像几乎没有区别,并且仅占用5189字节,比JPEG图像得多。我敢肯定它可以进一步优化,但这实际上只是您可以在几分钟内完成练习的一个示例。(输入此答案比实际编辑SVG代码花更长的时间。)

最后,使用gzip压缩此SVG代码会将其压缩到仅1846字节(!),仅略高于JPEG版本的四分之一。


4
奈斯利golfed
Wrzlprmft

7
摆脱换行符,您
将再

15
我不得不加入这个网站只是为了赞美这个答案!做得好!
Karl-

嘿,伊尔马里,我想知道您是否可以查看我在答案中链接的Web应用程序,并确认它是否可以手动完成所有操作?我在一个大型SVG上运行了它,并且减少了很多,但是当我还通过另一个服务运行该SVG时,我又可以节省2kb。当我检查SVG代码时,我仍然看到一些带有Adobe链接的元数据,并且我不知道是否有必要。非常感谢您的SVG知识。
Dom

30

令我惊讶的是,没有人提到“ Scour ”扩展名。它与Inkscape捆绑在一起(从v0.47开始),并且进行了Ilmari Karonen提到的许多优化。


14
+1太棒了!老实说,我什至没有意识到这个工具的存在。使用正确的选项,命令行版本甚至可以将我的手动优化代码击败近200个字节,并且在手动优化代码运行它可以将其压缩为4571字节(!)。
Ilmari Karonen 2015年

5

您可以将其转换为压缩的SVG(SVGZ),然后将image.svgz放在您的网页上:

gzip image.svg
mv image.svg.gz image.svgz

或者,在Adobe Illustrator中,只需将其另存为“ SVG压缩”,即可写入image.svgz文件。

对于您的测试图像,它仍然比JPG大,但:

image.jpg:   7268 bytes
image.svg:  22385 bytes
image.svgz: 14614 bytes

6
不幸的是,压缩的SVG在大多数(即使不是全部)最新IE中也无法正常工作。这个想法很有帮助,但是IE使其可行性大大降低。无论如何+1是因为不是您的错IE $ ucks。:)
Dom 2015年

5
@Dom,使用IE和PNG的经验表明需要3-5年而不是几年。
Glenn Randers-Pehrson

3
扑IE浏览器永远不会停止逗我!:)很酷,我们可以吸引您经验丰富的人来GDSE,我希望您在这里喜欢它,如果还没有人说,欢迎您!
Dom 2015年

2
要在IE中进行测试,您可以使用modern.ie/zh-cn中
Scott Carlson

4
如果您在网站上提供服务,这对于请求HTTP压缩的客户端(无论如何通常使用gzip)提供的好处微不足道。
鲍勃

3

我最近在https://petercollingridge.appspot.com/svg-editor源代码)找到了一个工具,可以帮助优化SVG文件。在这种情况下,它具有很好的效果,文件大小减小到3.7kB,这是JPG大小的一半多一点,并且进行了一些手动调整:

使用该工具优化SVG文件所需的时间比手动打高尔夫球所需的时间少得多。


欢迎来到平面设计SE。请注意,提问者在问题中提到了这个工具。并不是说这会使这个答案无效,但是您可以将其放在透视图中。另外,手动调整
Wrzlprmft

这与问题中提到的工具不太相同,但是它是由同一位作者创建的,并且位于同一域中。作者的链接确实具有指向此工具的链接,但是直到发布答案后我才注意到它。我没有删除它,因为它仍然有用。通过手动调整,我的意思是我未选中几个框(组合路径,删除ID)以使输出正确,并降低了小数位以进一步提高尺寸。
user60561

与SVGOMG(来自Dom的答案)一样,在这里最大的节省似乎来自禁用xlink,这是一个副作用,它完全删除了嵌入式图像。显然,用渐变代替图像并不是您可以期望自动化工具真正完成的事情。
Ilmari Karonen 2015年

3

SVGOMG!是用于SVG优化的出色Web应用程序

根据该应用的创建者,SVGOMG是SVGO的‘ 中号伊辛ģ UI’。

在提供的图像上运行它可以将其压缩为just 3.42kb,并且1.4kb压缩后即可。

SVGOMG屏幕截图


1
查看渲染的预览图,似乎大部分节省是由于它完全删除了嵌入式图像。显然,用渐变代替位图并不是人们期望软件工具自动完成的事情。
Ilmari Karonen 2015年

1
我没有仅优化了梯度的未优化版本,但是如果我手动编辑原始SVG以将位图替换为最后一个,<radialGradient><path>通过我的手动优化代码,SVGOMG会将最终的5.8 kB图像优化为4.02 kB(预设为4.11 kB),似乎做得相当透彻;我真的看不到任何明显的错失机会。(更多地使用它,我确实注意到它有时无法合并具有相同attrs的连续组; Inkscape有时似乎会生成这些组,例如,在调整页面以适合绘图时。)
Ilmari Karonen 2015年

@IlmariKaronen感谢您的关注,在Dropbox的原始22kb SVG上运行它对我来说将其降低到磁盘上的3.42kb,我知道为什么我的体积更小了吗?(我确实启用了每个选项)。在大多数情况下,此应用可能是最好的(最简单/最快捷)选项。我与该应用没有任何关系,太棒了!
Dom

1
仔细观察控制器:优化原始SVG时,如果选择“删除栅格图像”,则控制器上的阴影会完全消失(因为它实际上是嵌入式半透明的PNG)。如果您将答案中的屏幕截图与原始JPEG进行比较,则实际上可以看到它。我得到的4.02 kB版本更大,因为它包含一个额外的路径和渐变来替换已删除的阴影。
Ilmari Karonen 2015年

@IlmariKaronen我想我看到了区别,它是如此微小,我不确定我的眼睛是否在耍花招。很好,到目前为止,我只在SVG中使用纯色,所以以后我会记住这一点,谢谢。
Dom
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.