在所有浏览器中,小的非缩放SVG呈现模糊和错误

时间:2016-02-16 23:20:37

标签: html css svg graphics cross-browser

我有一个SVG,可以在所有浏览器中完全呈现。

这里有很多关于模糊SVG渲染的问题,但我看到的所有问题都是特定于某些浏览器,或涉及缩放,或应用变换,或使用SVG滤镜,或用作背景图像等。

这不是放大或缩小的,并且没有过滤器或任何有趣的东西,只是<svg>元素中的单个路径。它是24x24px。当我放大它看起来很好,它在视网膜屏幕上看起来很棒。

左边是Sketch中的图像(在Illustrator中看起来同样好)。右侧是OS X上的Chrome,Safari和Firefox中的图像。在3个图标中,顶部是正常的,中间有transform: rotate(0.1deg)(看到有些人在那里取得了一些成功),在底部它有shape-rendering: crispEdges。他们都很讨厌:

crappy SVG rendering

在Windows机器上看起来不同程度,包括在IE中。

这是SVG:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
    <g id="Production" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
        <g id="Desktop-Web-Feed" sketch:type="MSArtboardGroup" transform="translate(-110.000000, -504.000000)">
            <g id="Share" sketch:type="MSLayerGroup" transform="translate(26.000000, 504.000000)">
                <g id="Facebook" transform="translate(84.000000, 0.000000)" sketch:type="MSShapeGroup">
                    <g id="icon-web-feed-fb">
                        <rect id="Bounds" opacity="0.30626166" x="0" y="0" width="24" height="24"></rect>
                        <path d="M10,19 L10,12.9000244 L8,12.9000244 L8,10.9108276 L10,10.9108276 L10.0697378,8.28793345 C10.0697378,6.15850696 11.3218994,5 13.1515237,5 C14.02764,5 14.7807229,5.06596481 15,5.09688581 L15,7.32319812 L13.7299787,7.32319812 C12.7377746,7.32319812 12,7.70703125 12,8.53530148 L12,10.9108276 L14.8771973,10.9108276 L14.6080794,12.9000244 L12,12.9000244 L12,19 L9.1929245,19" id="Shape" stroke="#A1A1A1"></path>
                    </g>
                </g>
            </g>
        </g>
    </g>
</svg>

以下是我尝试过的一些不起作用的事情:

  • 从Illustrator导出SVG,路径值四舍五入到小数点后1位(不会让我做0小数位),看看它是否与像素边界的落差有关。
  • 导出“更大”(更大的视图框和路径展开以适应它)SVG并在浏览器中缩小它。这看起来略微更好,但仍然不够好。
  • 使用stroke-width - 只是让它看起来很糟糕,但方式不同。
  • 各种CSS转换旨在改善此类问题,+ shape-rendering的所有选项+放大图片并再次transform: scale

奇怪的是,SVG的基本布局在浏览器中完全不同 - 字母内部应该有2个像素的空间,但即使是清晰的抗锯齿,所有浏览器中只有1个像素的空间。

有没有办法改善这个?这与特定的SVG有关吗?或者只是浏览器在渲染小型SVG时非常糟糕?

2 个答案:

答案 0 :(得分:3)

尝试SVG时的结果并不像屏幕截图那么糟糕。所以我不确定为什么会这样。草图看起来可能会碰撞几何体以与像素边界对齐 - 与字体渲染器不同。

通过考虑形状的轮廓与像素边界的关系,您可以显着改善图标的外观。

如果你稍稍炸掉你的图标,并绘制对应于24x24像素渲染的网格线,你会看到我的意思:

var grid = document.getElementById("grid");
for (var i=1; i<24; i++) {
  var line = document.createElementNS("http://www.w3.org/2000/svg", "line");
  line.setAttribute("x1", 0);
  line.setAttribute("y1", i);
  line.setAttribute("x2", 24);
  line.setAttribute("y2", i);
  grid.appendChild(line);
  line = document.createElementNS("http://www.w3.org/2000/svg", "line");
  line.setAttribute("x1", i);
  line.setAttribute("y1", 0);
  line.setAttribute("x2", i);
  line.setAttribute("y2", 24);
  grid.appendChild(line);
}
<svg id="mysvg" width="240px" height="240px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
    <g id="Production" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
        <g id="Desktop-Web-Feed" sketch:type="MSArtboardGroup" transform="translate(-110.000000, -504.000000)">
            <g id="Share" sketch:type="MSLayerGroup" transform="translate(26.000000, 504.000000)">
                <g id="Facebook" transform="translate(84.000000, 0.000000)" sketch:type="MSShapeGroup">
                    <g id="icon-web-feed-fb">
                        <rect id="Bounds" opacity="0.30626166" x="0" y="0" width="24" height="24"></rect>
                        <path d="M10,19 L10,12.9000244 L8,12.9000244 L8,10.9108276 L10,10.9108276 L10.0697378,8.28793345 C10.0697378,6.15850696 11.3218994,5 13.1515237,5 C14.02764,5 14.7807229,5.06596481 15,5.09688581 L15,7.32319812 L13.7299787,7.32319812 C12.7377746,7.32319812 12,7.70703125 12,8.53530148 L12,10.9108276 L14.8771973,10.9108276 L14.6080794,12.9000244 L12,12.9000244 L12,19 L9.1929245,19" id="Shape" stroke="#A1A1A1"></path>
                    </g>
                </g>
            </g>
        </g>
    </g>
    <g id="grid" fill="none" stroke="#ccd" stroke-width="0.1">
    </g>
</svg>

你可以看到你的形状线正好落在最终像素的中间。这将导致最坏的抗锯齿。你应该考虑调整你的图标设计来移动线条,使它们与像素更好地对应。在Sketch中打开网格线并将其设置为显示像素边界。从那里开始工作。

答案 1 :(得分:1)

不幸的是,你可能不会在那个尺寸上获得更好的结果。大多数情况下,它是你试图渲染它的大小,虽然颜色也没有多大帮助 - 低对比度的子像素渲染根本不可能很好。虽然像素大小为24x24,但你只剩下大约10个像素来渲染SVG。没有多少图标看起来非常好10px。

判断问题是否与SVG渲染器有关的一种简单方法是将其渲染为双倍大小(或更大),然后使用位图重采样算法(大多数标准的高质量图像编辑器)将其缩小。

尝试在iConvert图标SVG icon converter上进行转换。首先上传SVG;它将重新绘制每个尺寸 - 注意32px以下它开始变得有点模糊。

然后,抓住256x256 图像,看起来很漂亮,并通过图标转换器运行 。请注意结果看起来几乎完全相同 - 尽管源是图像,而不是一些缩小的SVG。

说到这里,我对代码进行了一些小改动(删除了一些不必要的转换,使图标变暗,并使其填充而不是笔划),我认为它有助于提高对比度(因此,“锐度” “)小尺寸:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
    <g id="Production" stroke="none" stroke-width="0.8" fill="none" sketch:type="MSPage">
        <path d="M10,19 L10,12.9000244 L8,12.9000244 L8,10.9108276 L10,10.9108276 L10.0697378,8.28793345 C10.0697378,6.15850696 11.3218994,5 13.1515237,5 C14.02764,5 14.7807229,5.06596481 15,5.09688581 L15,7.32319812 L13.7299787,7.32319812 C12.7377746,7.32319812 12,7.70703125 12,8.53530148 L12,10.9108276 L14.8771973,10.9108276 L14.6080794,12.9000244 L12,12.9000244 L12,19 L9.1929245,19" id="Shape" fill="#222222"></path>
    </g>
</svg>