2014-03-25 50 views
0

我想显示图像并在顶部应用一个遮罩,以使整个图像变暗,除了一些区域会保留原始内容的形象。 就像使用带有孔的面罩一样。SVG:突出显示图像的多个部分(合成)

我一直在尝试很多选择,但我无法让它工作。 这是我得到的最接近:在面具

<image id="image1" xlink:href="image.png" height="100%" width="100%" /> 
<g if="image1mask" > 
    <circle id="image1maskhole" cx="160" cy="120" r="80" fill="black" fill-opacity="100%" /> 
    <rect id="image1maskbase" x="0" y="0" width="100%" height="100%" fill="rgb(100, 100, 100)" fill-opacity="30%" comp-op="dst-out"/> 
</g> 

然而,圆填充(黑色)。我希望它完全透明。 我试着用白色代替,但结果也是错的。 我也尝试玩填充不透明度值,但我无法使其工作。

我在Chrome上测试,但我要在嵌入式浏览器中运行它,它不能很好地处理蒙版。这就是为什么我回避这个可能的解决方案(即在Chrome完美的作品):

<defs> 
    <mask id="image1mask" > 
     <rect x="0" y="0" width="100%" height="100%" fill="white" fill-opacity="30%" /> 
    <polygon points="30,30, 80,30, 50,120, 80,210, 30,210" fill="white" /> 
     <circle cx="160" cy="120" r="80" fill="white" /> 
    <rect x="250" y="30" width="50" height="180" fill="white" /> 
    </mask> 
</defs> 
<image id="image1" xlink:href="image.png" height="100%" width="100%" mask="url(#image1mask)" /> 

任何人的帮助,好吗?

非常感谢。

----可能的解决方案:

我找到了一种方法来做到这一点。这实际上是一种解决方法,我对性能有点担心。 我将它嵌入到JavaFX2应用程序中。不幸的是它不能很好地工作。 掩码实际上将被解释为一个矩形,其中包含掩码1的所有项目。 所以回到开始。

<svg class="svg-graphic" width="320" height="240" > 
    <defs> 
     <clipPath id="mask1"> 
      <polygon points="30,30, 80,30, 50,120, 80,210, 30,210" fill="white" /> 
      <circle cx="160" cy="120" r="80" fill="white" /> 
      <rect x="250" y="30" width="50" height="180" fill="white" /> 
     </clipPath> 
    </defs> 

    <image id="backimage" xlink:href="image.png" height="100%" width="100%" style="opacity:0.3" /> 
    <image id="imagemask" xlink:href="image.png" height="100%" width="100%" clip-path="url(#mask1)"/> 
</svg> 

- 另一种可能的解决方案:这个解决方案可以在嵌入式浏览器中使用。

唯一的缺点是它使用了很多“假”图像。一个用于背景(阴影),另一个用于蒙版中的每个孔(非阴影部分)。性能可能再次受损。

<svg class="svg-graphic" width="320" height="240" > 
    <image id="image1back" xlink:href="image.png" height="100%" width="100%" style="opacity:0.3" /> 
    <g id="mask4" visibility="visible"> 
     <defs> 
      <clipPath id="mask4def-1"><polygon points="30,30, 80,30, 50,120, 80,210, 30,210" /></clipPath> 
      <clipPath id="mask4def-2"><circle cx="160" cy="120" r="50" /></clipPath> 
      <clipPath id="mask4def-3"><rect x="250" y="30" width="50" height="180" /></clipPath> 
     </defs> 
     <image xlink:href="image.png" height="100%" width="100%" clip-path="url(#mask4def-1)"/> 
     <image xlink:href="image.png" height="100%" width="100%" clip-path="url(#mask4def-2)"/> 
     <image xlink:href="image.png" height="100%" width="100%" clip-path="url(#mask4def-3)"/> 
    </g> 
</svg> 

这将导致与上面给出的掩蔽方法(在我的嵌入式浏览器中不起作用)相同的结果。 有谁知道这是否是一个有问题的方法? 任何人有更好的想法?

+0

我假设你的嵌入式浏览器不支持SVG过滤器? –

+0

当你说JavaFX WebView“不能很好地处理掩码”时,你是什么意思? –

回答

0

BigBadaboom提供的两种解决方案在Chrome中都能很好地工作。 但是,我必须使用JavaFX2嵌入式浏览器,这些解决方案将无法很好地工作。据我了解,它并没有很好地管理口罩。 另一个限制与clippath中的多个项目有关。浏览器实际上将它们理解为一个足够大的单个矩形,以将所有项目放在其中。

我可以使它在嵌入式浏览器中工作的唯一方法是对图像进行叠加。 我从底图完全着色开始。然后我添加一个图像,并为每个我想要的突出部分添加一个剪辑路径。

到目前为止,性能还是可以接受的。但是,我不会建议任何人在使用普通浏览器时遵循此方法。如果您在单个页面中多次使用它,它可能会变慢。

<svg class="svg-graphic" width="320" height="240">http://placepuppy.it/320/240 
    <image id="image1back" xlink:href="http://placepuppy.it/320/240" height="100%" width="100%" /> 
    <rect height="100%" width="100%" fill="black" style="opacity:0.6" /> 
    <g id="mask4" visibility="visible"> 
     <defs> 
      <clipPath id="mask4def-1"> 
       <polygon points="30,30, 80,30, 50,120, 80,210, 30,210" /> 
      </clipPath> 
      <clipPath id="mask4def-2"> 
       <circle cx="160" cy="120" r="50" /> 
      </clipPath> 
      <clipPath id="mask4def-3"> 
       <rect x="250" y="30" width="50" height="180" /> 
      </clipPath> 
     </defs> 
     <image xlink:href="http://placepuppy.it/320/240" height="100%" width="100%" clip-path="url(#mask4def-1)" /> 
     <image xlink:href="http://placepuppy.it/320/240" height="100%" width="100%" clip-path="url(#mask4def-2)" /> 
     <image xlink:href="http://placepuppy.it/320/240" height="100%" width="100%" clip-path="url(#mask4def-3)" /> 
    </g> 
</svg> 

Demo here

1

尝试是这样的:

<defs> 
    <mask id="image1mask" > 
    <g> 
     <rect id="image1maskbase" x="0" y="0" width="100%" height="100%" fill="rgb(100, 100, 100)" fill-opacity="30%" /> 
     <circle id="image1maskhole" cx="160" cy="120" r="80" fill="black" /> 
    </g> 
    </mask> 
</defs> 

<image id="image1" xlink:href="image.png" height="100%" width="100%" mask="url(#imagemask)" /> 
+0

感谢您的回答。请按照您的方法检查我刚刚编制的工作解决方案。它适用于Chrome,但在我正在使用的嵌入式浏览器中无法正常工作。我必须找到另一个解决方案,而不使用蒙版。 – Marcus

+0

我发现了一种方法来创建一个面具,就像我的例子中提供的一个面具一样,除了它在透明的地方是阴影和阴影的地方是透明的。我需要反对。 我用填充不透明度设置的几何形式。但是我不能使用合成技术来获得我想要的。 – Marcus

1

我现在有点不清楚哪些位你想要的阴影以及哪些位,你要清楚:/

我会假设你想要的“锦鲤”形状清晰,其余黑暗。这是一个解决方案,可以不使用蒙版。

<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="320" height="240" > 
    <defs> 
     <clipPath id="mask1"> 
      <polygon points="30,30, 80,30, 50,120, 80,210, 30,210"/> 
      <circle cx="160" cy="120" r="80" /> 
      <rect x="250" y="30" width="50" height="180" /> 
     </clipPath> 
    </defs> 

    <image xlink:href="http://placepuppy.it/320/240" height="100%" width="100%" /> 
    <rect height="100%" width="100%" fill="black" opacity="0.6" /> 
    <image xlink:href="http://placepuppy.it/320/240" height="100%" width="100%" clip-path="url(#mask1)"/> 
</svg> 

Demo here

还存在只需要一个<image>元素的解决方案,但你需要将“KOI”字形组合成一个单一的<path>元素。

+0

这正是我想要做的。我实际上设法做的几乎和你一样,但它不能在我必须使用的嵌入式浏览器中工作。所以我不能这样做。我能做到的唯一方法就是我在第一篇文章(editted)中描述的第二种可能的解决方案。非常感谢您的回答。这给了我解决这个问题的基本想法。 – Marcus