【问题标题】:Inlining SVG filters as data URI内联 SVG 过滤器作为数据 URI
【发布时间】:2018-09-06 11:40:59
【问题描述】:

我正在尝试使用 CSS 中的数据 URI 添加 SVG 过滤器,但无法将效果应用于我的图像。

似乎应该支持它,因为根据“caniuse”,所有主要浏览器都支持数据 URI 和 SVG 过滤器。如果我将它保存为 SVG 文件并链接到 css 中的文件,过滤器就可以正常工作。

我已尝试将 SVG 编码为 base64 并使用 url 编码文件,但无济于事。

以下是此类滤镜的示例,该滤镜使应用滤镜的图像变为黑白。

<svg xmlns="http://www.w3.org/2000/svg">
    <filter id="light">
        <feColorMatrix type="matrix" result="grayscale--light"
            values="1 0 0 0 0
                    1 0 0 0 0
                    1 0 0 0 0
                    0 0 0 1 0">
        </feColorMatrix>
    </filter>
</svg>

在对 SVG 进行编码后,我创建了一个具有以下样式的类

.grayscale--light {
    filter: url("data:image/svg+xml;base64,base64encodedString")
}

在我的 HTML 中

<img src="/path/to/my/image.jpg" class="grayscale--light">

我做错了什么,还是不再受支持?我找到的所有关于该主题的文章都来自 2014 年左右。

【问题讨论】:

  • 不支持,edge 几乎不支持 svg。您仍然可以使用画布对图像进行灰度化。 html5canvastutorials.com/advanced/…
  • 请提供最低限度的可验证测试用例。您没有显示您正在使用的编码。 [通常你需要一个片段 ID 来引用过滤器,所以我不知道你是如何让过滤器在没有它的单独 svg 文件中工作的。这也不是真正的灰度滤镜 - 它是红色通道滤镜 - 它将红色通道值复制到蓝色和绿色通道中并丢弃现有的蓝色和绿色值(例如,它会给你非常黑的天空)
  • 灰度只是一个最小的例子。我正在创建一个结合了 feColorMatrix 和 feComponentTransfers 的过滤器。通常我会将它们放在一个 .svg 文件中 并使用 ID 过滤器引用过滤器:url(path/to/filter.svg#filterID)。但是,我正在尝试动态创建过滤器,这就是为什么我需要将过滤器内联作为数据 uri。我试图在jsfiddle.net/57dyw33m/5 重新创建一个示例

标签: html css svg data-uri svg-filters


【解决方案1】:

首先,您必须在数据 URI 的末尾引用 filter id,例如:...VyPg0KPC9zdmc+#filterID)。现在它可以在 Firefox 中运行,但不能在 Chrome 中运行,这会引发错误:

Unsafe attempt to load URL (...) from frame with URL <URL>. Domains, protocols and ports must match.

所以 Chrome 不喜欢数据 URI,并且想要一个正确的 URL,其域与当前站点匹配。有一种方法可以做到这一点:不要对 SVG 进行 data-URI 编码,而是将其放入 Blob 并在 JavaScript 中为其生成 URL:

const svg = '<svg xmlns="http://www.w3.org/2000/svg"><filter id="filterID"> ... </svg>',
      blob = new Blob([svg], { type: 'image/svg+xml' }),
      url = URL.createObjectURL(blob);

myImage.style.filter = `url('${url}#filterID')`;

https://jsfiddle.net/57dyw33m/7/

【讨论】:

  • 我想这是正确的答案!太感谢了!显然,目前支持不是很好。我想做的是一个 postCSS 插件,因此只能访问 CSS 文件,因此只能访问内联 SVG 过滤器。我想 DOM 中的 javascript 解决方案和 SVG 过滤器之间的区别在性能方面不值得,如果我必须选择,我会选择 HTML 解决方案而不是 javascript 解决方案。但是您的解决方案在我测试过的浏览器中有效,所以我会接受您的回答
  • 2020 年,这适用于 Chrome。示例:codepen.io/DanielWeiner/full/YzwLNxR。我还用 对其进行了测试,但它似乎不适用于内联数据 URL SVG 过滤器。
猜你喜欢
  • 2016-11-17
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2021-12-24
相关资源
最近更新 更多