SVG:突出显示图像的多个部分(合成) [英] SVG: Highlight multiple parts of an image (compositing)

查看:23
本文介绍了SVG:突出显示图像的多个部分(合成)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想显示一个图像并在其上应用一个蒙版,这会使整个图像变暗,除了一些会保留图像原始内容的区域.就像使用有孔的面具一样.

I'd like to show an image and apply a mask on top of that that would make the entire image darker, except for a number of regions that would keep the original content of the image. Something like using a mask with holes in it.

我尝试了很多选择,但我无法让它发挥作用.这是我最接近的:

I've been trying a lot of options, but I couldn't make it work. That's the closest I've got:

<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>

但是,圆在蒙版中被填充(黑色).我希望它完全透明.我尝试使用白色代替,但结果也是错误的.我也尝试过使用填充不透明度值,但我也无法让它工作.

However, the circle is filled (black) in the mask. I'd like it to be totally transparent. I tried using white instead, but the result is also wrong. I also tried playing with the fill-opacity values, but I couldn't make it work either.

我正在 chrome 上进行测试,但我将在不能很好地处理掩码的嵌入式浏览器中运行它.这就是为什么我要避免这种可能的解决方案(在 chrome 上效果很好):

I'm testing on chrome, but I'm going to run it in an embedded browser that doesn't handle masks very well. That's why I'm avoiding this possible solution (that works perfectly on 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)" />

有人可以帮忙吗?

非常感谢.

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

---- Possible solution:

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

I found a way to do that. It is actually a workaround, and I'm a bit concerned about performance. I'm embedding this into a JavaFX2 application. And unfortunelly it doesn't work very well. The mask will actually be interpreted as a rectangle that encloses all items of mask1 in it. So back to the beginning.

    <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>

-- 另一种可能的解决方案:此方法适用于嵌入式浏览器.

-- Another possible solution: This one works in the embedded browser.

唯一的缺点是它使用了大量假"图像.一个用于背景(阴影),一个用于遮罩中的每个孔(非阴影部分).再一次,性能可能会受到影响.

The only drawback is that it uses a lot of "fake" images. One for the background (shaded) and one for each hole in the mask (non shaded parts). Once again, performance may suffer.

    <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>

它会产生与我上面给出的掩蔽方法相同的结果(在我的嵌入式浏览器中不起作用).有谁知道这是否是一种有问题的方法?有人有更好的想法吗?

It will result in the same result as the Masking approach I give in above (that won't work in my embedded browser). Does anyone knows whether it is a problematic approach or not? Anyone with better ideas?

推荐答案

BigBadaboom 提供的两种解决方案在 Chrome 中都运行良好.但是,我必须使用 JavaFX2 嵌入式浏览器,这些解决方案不会很好地工作.据我所知,它并不能很好地管理面具.另一个限制与剪辑路径中的多个项目有关.浏览器实际上会将它们理解为一个更大的矩形,足以容纳其中的所有项目.

Both solutions provided by BigBadaboom work very well in Chrome. However, I have to use the JavaFX2 embedded browser and those solutions won't work very well. As far as I understood, it doesn't manage masks very well. Another limitation is related to multiple items in a clippath. The browser will actualy understand them as a single rectangle bigger enought to hold all items inside it.

我可以让它在嵌入式浏览器中工作的唯一方法是叠加图像.我从完全着色的基本图像开始.然后我添加一张图片,并为我想要的每个突出显示的部分添加一个剪辑路径.

The only way I could make it work in the embedded browser was doing superposition of images. I started with the base image entirely shaded. Then I add one image, with a clip-path for each highlighted part I desire.

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

Up to now, performance is acceptable. However I wouldn't suggest anyone to follow this approach when using normal browsers. It will probably be slower if you use it many times in a single page.

<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>

此处演示

这篇关于SVG:突出显示图像的多个部分(合成)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆