【问题标题】:SVG makes white lines in the browserSVG 在浏览器中生成白线
【发布时间】:2018-11-14 22:21:35
【问题描述】:

我制作了一个 24x24 像素的徽标。它由并排的多边形组成。

我在我的网页上以 40 像素24 像素 范围内的各种尺寸显示此内容。

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<polygon points="6,20 4,16 2,20 "/>
<polygon points="4,16 2,12 0,16 "/>
<polygon points="6,12 4,8 2,12 "/>
<polygon points="8,8 6,4 4,8 "/>
<polygon points="10,12 8,8 6,12 "/>
<polygon points="14,12 12,8 10,12 "/>
<polygon points="18,12 16,8 14,12 "/>
<polygon points="22,12 20,8 18,12 "/>
<polygon points="12,16 10,12 8,16 "/>
<polygon points="20,16 18,12 16,16 "/>
<polygon points="4,16 6,20 8,16 "/>
<polygon points="2,12 4,16 6,12 "/>
<polygon points="0,16 2,20 4,16 "/>
<polygon points="4,8 6,12 8,8 "/>
<polygon points="6,4 8,8 10,4 "/>
<polygon points="8,8 10,12 12,8 "/>
<polygon points="16,8 18,12 20,8 "/>
<polygon points="18,12 20,16 22,12 "/>
<polygon points="10,12 12,16 14,12 "/>
<polygon points="8,16 10,20 12,16 "/>
<polygon points="16,16 18,20 20,16 "/>
<polygon points="20,16 22,20 24,16 "/>
<polygon points="10,20 8,16 6,20 "/>
<polygon points="14,20 12,16 10,20 "/>
<polygon points="18,20 16,16 14,20 "/>
<polygon points="22,20 20,16 18,20 "/>
</svg>

但是 svg 元素之间会形成白线... 例如:

原始 svg 文件:bz.svg

我无法将它们组合起来,因为在某些情况下,我会分别为每一个上色。我该如何解决这个问题?

【问题讨论】:

  • 听起来像是一个循环问题。也许您可以在每个元素周围添加一个细边框,以便以较小的尺寸隐藏它?
  • @Tordek 你的意思是,我应该设计一个更大的尺寸并添加一个描边像素吗?因为当我在“24px”中添加描边时会破坏图像。
  • 对;你可以把它放大 100 倍,并在每个元素周围添加 1 像素的笔触。
  • @Tordek 非常感谢,我尝试从 24 像素高出 x100(240 像素)。我添加了 1px 边框(笔划)......不幸的是,不同尺寸存在问题,例如滑动或重叠。即使是某些尺寸的调光线也会出现。因为我从原始的“240px”显示它“24px”。因此,1px 边框使 1/100px(0,01px 边框):D

标签: svg polygon adobe-illustrator


【解决方案1】:

shape-rendering 在大多数情况下会有所帮助。但不能保证。您仍然可能会发现奇怪的白色像素。此外,它还有一个缺点,就是您会失去外边缘的抗锯齿功能。使倾斜的边缘“锯齿状”。

正如其他人所建议的那样,另一种解决方案是为您的形状添加细笔触。该笔划需要的宽度将取决于连接线的斜率,以及浏览器使用的 2D 渲染引擎。

第三种解决方案是合并相邻的三角形,如果它们是相同的颜色。您可以编写一些 javascript 来进行合并。您可能不必担心具有不同颜色的相邻三角形。如果颜色足够不同,那么轻微的白线可能不会很明显。

第四个选项类似。不要合并三角形,而是寻找后来的三角形紧靠的三角形的边缘,并给这些边一个“凸起”。例如,通过在该边的中间使用一个额外的点,这会有点突出。这个想法是早期的三角形在后面的三角形下方延伸。

我能想到的一个最终解决方案是对形状运行过滤器以去除抗锯齿伪影。

理想的过滤器是中值过滤器,但不幸的是,SVG/CSS 没有中值过滤器。 Michael Mullany 创建了a very clever hack,它使用可用的滤波器原语组合来模拟中值滤波器。

<svg version="1.1" id="katman_1" viewBox="0 0 24 24">
  <defs>
    <filter id="median">
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 1 0 0 0 0 0" result="1" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="1 0 0 0 0 0 0 0 0" result="2" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 1 0 0 0 0 0 0 0" result="3" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 1 0 0 0 0 0 0" result="4" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 1 0 0 0" result="5" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 0 0 1" result="6" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 0 1 0" result="7" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 1 0 0" result="8" preserveAlpha="true" />
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 1 0 0 0 0" result="9" preserveAlpha="true" />
      <feBlend in="1" in2="2" mode="lighten" result="a1"/>
      <feBlend in="1" in2="2" mode="darken" result="a2"/>
      <feBlend in="a2" in2="3" mode="lighten" result="a3"/>
      <feBlend in="a2" in2="3" mode="darken" result="a4"/>
      <feBlend in="a4" in2="4" mode="lighten" result="a5"/>
      <feBlend in="a4" in2="4" mode="darken" result="a6"/>
      <feBlend in="a6" in2="5" mode="lighten" result="a7"/>
      <feBlend in="a6" in2="5" mode="darken" result="a8"/>
      <feBlend in="a8" in2="6" mode="lighten" result="a9"/>
      <feBlend in="a8" in2="6" mode="darken" result="a10"/>
      <feBlend in="a10" in2="7" mode="lighten" result="a11"/>
      <feBlend in="a10" in2="7" mode="darken" result="a12"/>
      <feBlend in="a12" in2="8" mode="lighten" result="a13"/>
      <feBlend in="a13" in2="8" mode="darken" result="a14"/>
      <feBlend in="1" in2="2" mode="lighten" result="a15"/>
      <feBlend in="1" in2="2" mode="darken" result="a16"/>    
      <feBlend in="a1" in2="a3" mode="lighten" result="b1"/>
      <feBlend in="a1" in2="a3" mode="darken" result="b2"/>
      <feBlend in="b2" in2="a5" mode="lighten" result="b3"/>
      <feBlend in="b2" in2="a5" mode="darken" result="b4"/>
      <feBlend in="b4" in2="a7" mode="lighten" result="b5"/>
      <feBlend in="b4" in2="a7" mode="darken" result="b6"/>
      <feBlend in="b6" in2="a9" mode="lighten" result="b7"/>
      <feBlend in="b6" in2="a9" mode="darken" result="b8"/>
      <feBlend in="b8" in2="a11" mode="lighten" result="b9"/>
      <feBlend in="b8" in2="a11" mode="darken" result="b10"/>
      <feBlend in="b10" in2="a13" mode="lighten" result="b11"/>
      <feBlend in="b10" in2="a13" mode="darken" result="b12"/>
      <feBlend in="b12" in2="a15" mode="lighten" result="b13"/>
      <feBlend in="b12" in2="a15" mode="darken" result="b14"/>
      <feBlend in="b1" in2="b3" mode="lighten" result="c1"/>
      <feBlend in="b1" in2="b3" mode="darken" result="c2"/>
      <feBlend in="c2" in2="b5" mode="lighten" result="c3"/>
      <feBlend in="c2" in2="b5" mode="darken" result="c4"/>
      <feBlend in="c4" in2="b7" mode="lighten" result="c5"/>
      <feBlend in="c4" in2="b7" mode="darken" result="c6"/>
      <feBlend in="c6" in2="b9" mode="lighten" result="c7"/>
      <feBlend in="c6" in2="b9" mode="darken" result="c8"/>
      <feBlend in="c8" in2="b11" mode="lighten" result="c9"/>
      <feBlend in="c8" in2="b11" mode="darken" result="c10"/>
      <feBlend in="c10" in2="b13" mode="lighten" result="c11"/>
      <feBlend in="c10" in2="b13" mode="darken" result="c12"/>
      <feBlend in="c1" in2="c3" mode="lighten" result="d1"/>
      <feBlend in="d1" in2="c3" mode="darken" result="d2"/>
      <feBlend in="d2" in2="c5" mode="lighten" result="d3"/>
      <feBlend in="d2" in2="c5" mode="darken" result="d4"/>
      <feBlend in="d4" in2="c7" mode="lighten" result="d5"/>
      <feBlend in="d4" in2="c7" mode="darken" result="d6"/>
      <feBlend in="d6" in2="c9" mode="lighten" result="d7"/>
      <feBlend in="d6" in2="c9" mode="darken" result="d8"/>
      <feBlend in="d8" in2="c11" mode="lighten" result="d9"/>
      <feBlend in="d8" in2="c11" mode="darken" result="d10"/>
      <feBlend in="d1" in2="d3" mode="darken" result="e1"/>
      <feBlend in="e1" in2="d5" mode="darken" result="e2"/>
      <feBlend in="e2" in2="d7" mode="darken" result="e3"/>
      <feBlend in="e3" in2="d9" mode="darken" result="e4"/>
    </filter>
  </defs>

  <g filter="url(#median)">
    <polygon points="6,20 4,16 2,20 "/>
    <polygon points="4,16 2,12 0,16 "/>
    <polygon points="6,12 4,8 2,12 "/>
    <polygon points="8,8 6,4 4,8 "/>
    <polygon points="10,12 8,8 6,12 "/>
    <polygon points="14,12 12,8 10,12 "/>
    <polygon points="18,12 16,8 14,12 "/>
    <polygon points="22,12 20,8 18,12 "/>
    <polygon points="12,16 10,12 8,16 "/>
    <polygon points="20,16 18,12 16,16 "/>
    <polygon points="4,16 6,20 8,16 "/>
    <polygon points="2,12 4,16 6,12 "/>
    <polygon points="0,16 2,20 4,16 "/>
    <polygon points="4,8 6,12 8,8 "/>
    <polygon points="6,4 8,8 10,4 "/>
    <polygon points="8,8 10,12 12,8 "/>
    <polygon points="16,8 18,12 20,8 "/>
    <polygon points="18,12 20,16 22,12 "/>
    <polygon points="10,12 12,16 14,12 "/>
    <polygon points="8,16 10,20 12,16 "/>
    <polygon points="16,16 18,20 20,16 "/>
    <polygon points="20,16 22,20 24,16 "/>
    <polygon points="10,20 8,16 6,20 "/>
    <polygon points="14,20 12,16 10,20 "/>
    <polygon points="18,20 16,16 14,20 "/>
    <polygon points="22,20 20,16 18,20 "/>
  </g>
</svg>

【讨论】:

    【解决方案2】:

    Shape Rendering 是你的罪魁祸首。

    只需将 shape-rendering="crispEdges" 添加到 svg 声明中(参见下面的源示例)... ....或者如果您喜欢在元素级别上点击多个 CSS,例如;

    svg {
      shape-rendering: crispEdges;
    }
    

    享受酷炫的图形;)

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve" 
    shape-rendering="crispEdges"> <!-- **** YOUR NEW FRIEND **** -->
      <polygon points="6,20 4,16 2,20 "/>
      <polygon points="4,16 2,12 0,16 "/>
      <polygon points="6,12 4,8 2,12 "/>
      <polygon points="8,8 6,4 4,8 "/>
      <polygon points="10,12 8,8 6,12 "/>
      <polygon points="14,12 12,8 10,12 "/>
      <polygon points="18,12 16,8 14,12 "/>
      <polygon points="22,12 20,8 18,12 "/>
      <polygon points="12,16 10,12 8,16 "/>
      <polygon points="20,16 18,12 16,16 "/>
      <polygon points="4,16 6,20 8,16 "/>
      <polygon points="2,12 4,16 6,12 "/>
      <polygon points="0,16 2,20 4,16 "/>
      <polygon points="4,8 6,12 8,8 "/>
      <polygon points="6,4 8,8 10,4 "/>
      <polygon points="8,8 10,12 12,8 "/>
      <polygon points="16,8 18,12 20,8 "/>
      <polygon points="18,12 20,16 22,12 "/>
      <polygon points="10,12 12,16 14,12 "/>
      <polygon points="8,16 10,20 12,16 "/>
      <polygon points="16,16 18,20 20,16 "/>
      <polygon points="20,16 22,20 24,16 "/>
      <polygon points="10,20 8,16 6,20 "/>
      <polygon points="14,20 12,16 10,20 "/>
      <polygon points="18,20 16,16 14,20 "/>
      <polygon points="22,20 20,16 18,20 "/>
    </svg>

    【讨论】:

    • Ty :) 我试过了。效果很好,我投票赞成。但似乎存在很多兼容性问题。 “caniuse.com/#feat=css-crisp-edges”已经低像素质量的图像质量也令人不安。也许还有另一种解决方案。否则我将强制合并。非常感谢。
    猜你喜欢
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 2011-12-28
    • 1970-01-01
    相关资源
    最近更新 更多