使用外部图像创建SVG背景图并进行遮罩处理失败。

3

我正在尝试将SVG图像用作CSS背景图像。这些SVG最终将使用许多大型JPEG图像(嵌入式或链接式)作为其他SVG元素的掩码。我这样做是为了节省文件大小,而不使用PNG。 (我的高度压缩的灰度JPEG非常小)

目前,我只能正确显示嵌入的base64编码图像,而Safari根本无法正常工作(除非使用嵌入来直接显示SVG)

以下是我的测试代码:

(所有图像均来自archive.org,链接应该持久存在-我已省略了base64编码数据)

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="application/xhtml+xml">
    <style type="text/css">
      body { font-family: Arial, sans; }
      .box1, .box2, .box3 { width: 400px; height: 100px; background-size: 192px 192px; margin: 10px 10px 0px 0px; padding: 10px; }
      .box1 { background: url("test1.svg"); }
      .box2 { background: url("test2.svg"); }
      .box3 { background: url("test3.svg"); }
      .sml { width: 100px; height: 100px; margin: 10px 10px 10px 0px; }
    </style>
  </head>
  <body>
    <div class="box1">Test 1</div>
    <div class="box2">Test 2</div>
    <div class="box3">Test 3</div>
    <img class="sml" src="test1.svg" type="image/svg+xml">
    <img class="sml" src="test2.svg" type="image/svg+xml">
    <img class="sml" src="test3.svg" type="image/svg+xml">
    <embed class="sml" src="test1.svg" type="image/svg+xml">
    <embed class="sml" src="test2.svg" type="image/svg+xml">
    <embed class="sml" src="test3.svg" type="image/svg+xml">
  </body>
</html>

嵌入式图片SVG的工作原理

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:cc="http://web.resource.org/cc/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:svg="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  x="0px" y="0px" width="192px" height="192px" viewBox="0 0 192 192">
  <style type="text/css" id="style_css_sheet">
    .orange { fill: #f9690e; }
    .yellow { fill: #f1d40f; }
  </style>
  <defs>
    <filter id="invert">
      <feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
    </filter>
    <rect id="box-bg" x="0" y="0" width="192px" height="192px" class="yellow" />
    <rect id="box-fg" x="0" y="0" width="192px" height="192px" class="orange" />
    <mask id="fg-mask" x="0" y="0" width="192px" height="192px" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse">
      <image id="mask-img" width="192px" height="192px" filter="url(#invert)"
        xlink:href="data:image/jpg;base64,
        [[ DATA ]]"></image>
    </mask>
  </defs>
  <use xlink:href="#box-bg" overflow="visible"></use>
  <use xlink:href="#box-fg" mask="url(#fg-mask)" overflow="visible"></use>
</svg>

图片链接变体损坏

  <mask id="fg-mask" x="0" y="0" width="192px" height="192px" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse">
    <image id="mask-img" width="192px" height="192px" filter="url(#invert)" xlink:href="http://bit.ly/1u61zrE"></image>
  </mask>

所以......Safari只支持嵌入标签,Chrome和Firefox可以使用背景,但只有在图像作为数据嵌入时才能使用。有没有办法让Safari工作,至少可以使用嵌入数据,这将是很好的。如果有一种方法可以让它们都正常工作,那就更好了......

谢谢。


2
出于隐私原因,SVG作为图像必须在一个文件中完整显示,请参阅http://longsonr.wordpress.com/2013/10/23/restrictions-on-svg-used-as-an-image/了解更多详细信息。 - Robert Longson
谢谢Robert - 这描述了我认为在幕后发生的事情。我推测Safari还不支持我所做的部分,因为我无法在任何情况下将我的SVG用作Safari的背景图像(嵌入式或链接图像)。 - rjmoggach
对于任何回答这个问题的人,只有当有可行的解决方案时我才会接受答案 - 正如Robert所指出的,它可能尚不可用,尽管我对不特定页面的javascript解决方法持开放态度。例如,如果类似于modernizr的东西通过预渲染并插入到不支持它的浏览器的DOM中提供了这个功能,那就太好了。(即。所有浏览器??) - rjmoggach
如果你在等待SVG作为图像支持外部图像数据,那么你将永远等下去。 - Robert Longson
罗伯特,您能将此作为答案添加,我会接受它。 - rjmoggach
我遇到了非常类似的问题。具体来说,我无法让使用图像元素的SVG文件引用其他包含在其中的SVG文件,这些文件并非外部文件,也就是说它们不来自于另一个网站或URL;相反,它们存在于我的网站上的同一目录中。就我所知,这不应该是安全或隐私问题,因为它们没有使用跨服务器引用,并且应该按预期工作。 - Tristan Bailey
2个回答

4

出于隐私原因,SVG作为图像必须在一个文件中完整展示。浏览器永远不会支持SVG作为图像中的外部引用。基本前提是,你只能像使用光栅图像一样使用SVG作为图像。

如果需要外部引用,请使用<object><iframe>


0
如Robert Longson所述,浏览器不会加载从SVG引用的外部文件,这些SVG被用作图像(HTML <img>或CSS背景图像)。 <embed>标签应该可以工作,并加载整个SVG和链接的图像。然而,<embed>最近才成为标准化,因此可能存在一些不一致性。为了确保最大的支持,请使用<object>标签和<embed>标签的混合使用:
<object class="sml" data="test1.svg" type="image/svg+xml">
    <embed class="sml" src="test1.svg" type="image/svg+xml" />
</object>

我实际上并不想将SVG嵌入到主文档中,而是将SVG用作背景图像。我已经知道了嵌入SVG的工作流程。(但无论如何,感谢您清晰地记录下来) - rjmoggach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接