将 SVG 过滤器内联为 URI 数据

Inlining SVG filters as data URI

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

似乎应该支持它,因为根据 "caniuse",所有主流浏览器都支持数据 URI 和 SVG 过滤器。如果我将其保存为 SVG 文件并将 link 保存到 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 进行编码后,我创建了一个具有以下样式的 class

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

在我的 HTML

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

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

首先,您必须在数据 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 域与当前站点匹配。有一种方法可以做到这一点:代替 data-URI-encoding SVG,将其放入 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/