将背景混合模式和灰度应用于图像的组合

3
我知道background-blend-mode是CSS的一个新特性,但我想知道它是否可以与CSS中的滤镜技术相结合。基本上,我想实现的是在悬停时,图像从全彩变为去饱和度并与彩色背景混合(混合模式为multiply)。下面是我尝试过的一个示例,你可以看到红色图像工作正常,因为它是暗色,但对于橙色和黄色,原始图像的颜色会透过黄色显示出来,因为它们更暗,所以图像需要去饱和度。最后一个示例#yellow2是我尝试实现去饱和度的方式,但这会导致图像忽略混合模式。

http://jsfiddle.net/cstr44/dzwH4/2/

<div id="red"></div>

<div id="orange"></div>

<div id="yellow"></div>

<div id="yellow2"></div>

    #red{
width:250px;
height:200px;
background:red url(http://www.mucky-pups.co/wp-content/uploads/2013/05/9.jpg);
background-size:250px 200px;}

#red:hover{
background-blend-mode: multiply; }

#orange{
width:250px;
height:200px;
background:orange url(http://0.tqn.com/d/friendship/1/S/R/-/-/-/special-dog-breeds.jpg); background-size:250px 200px;}

#orange:hover{
background-blend-mode: multiply;}

#yellow{ 
width:250px;
height:200px;
background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;}

#yellow:hover{ 
background-blend-mode: multiply;}

#yellow2{ 
width:250px;
height:200px;
background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;
}

#yellow2:hover{ 
background-blend-mode: multiply;
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
filter: gray;
-webkit-filter: grayscale(100%);}

除了创建每个图像的去饱和版本之外,还有其他可能的方法吗?

1个回答

1
我觉得我已经实现了你想要的。目前这个解决方案只在Chrome中起作用。
访问chrome://flags/并启用“启用实验性Web平台功能”以查看效果。
将过滤器和混合模式应用于同一元素的组合失败了。事实上,我尝试继续使用灰度滤镜来处理带有图像的元素,然后叠加一个新元素并尝试使用mix-blend-mode。那也失败了。
最终,我创建了两个新元素(层),位于您的图像上方。然后我使用mix-blend-mode来实现效果。第一个元素(位于图像上方的层)使用mix-blend-mode:饱和度,并具有黑色(或白色)背景颜色以将您的图像转换为灰度。最顶部的元素具有黄色颜色和mix-blend-mode:乘法。
我使用伪元素:before和:after,以便您可以保持标记不变。

http://jsfiddle.net/dzwH4/8/

<div id="red"></div>

<div id="orange"></div>

<div id="yellow"></div>

<div id="yellow2"></div>

#red{
width:250px;
height:200px;
background:red url(http://www.mucky-pups.co/wp-content/uploads/2013/05/9.jpg);
background-size:250px 200px;}

#red:hover{
background-blend-mode: multiply; }

#orange{
width:250px;
height:200px;
background:orange url(http://0.tqn.com/d/friendship/1/S/R/-/-/-/special-dog-breeds.jpg); background-size:250px 200px;}

#orange:hover{
background-blend-mode: multiply;}

#yellow{ 
width:250px;
height:200px;
background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;}

#yellow:hover{ 
background-blend-mode: multiply;}

#yellow2{ 
    width:250px;
    height:200px;
    background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;
    position: relative;
}

#yellow2:after, #yellow2:before {
    content: ' ';
    display: none;
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
}
#yellow2:before {
    background-color: black;
    mix-blend-mode: saturation;
}
#yellow2:after {
    background-color: yellow;
    mix-blend-mode: multiply;
}

#yellow2:hover:before, #yellow2:hover:after {
    display: block;
}

如果您正在寻找跨浏览器的解决方案,您可以使用SVG的feBlend(FF,IE10等)和dxFilters(IE <= 9)采用相同的方法。
更新:这是一个SVG解决方案,我在Chrome,FF,Opera,IE10,IE11,Safari 7 OSX上进行了测试。

http://jsfiddle.net/5pmmet6b/4/

<div id="puppy">
    <svg>
        <defs>
            <filter id="colorize_yellow" color-interpolation-filters="sRGB">
                <feFlood flood-color="yellow" result="A"/>
                <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="B"/>
                <feBlend mode="multiply" in2="B" in="A"/>
            </filter>
        </defs>
        <image id="yellow" filter="url(#colorize_yellow)" x="0" y="0" width="100%" height="100%" xlink:href="http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg"/>
    </svg>
</div>

#puppy {
    background: url('http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg');
    background-size: 249px 187px;
    position: relative;
}
#puppy svg {
    left: 0;
    overflow: hidden;
    position: absolute;
    top: 0;
}
#puppy, #puppy svg {
    height: 187px;
    width: 249px;
}
#yellow {
    opacity: 0;
}
#yellow:hover {
    opacity: 1;
}

旧版Internet Explorer方法:

适用于IE 6-9:

<!DOCTYPE html>

<html>

<head>
    <title>Light Filter Sample</title>
    <style type="text/css">
        div, img {
            height: 200px;
            width: 250px;
        }
        #image {
            position: relative;
        }
        #grayscale {
            -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";
            filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
        }
        #yellow {
            display: none;
            -ms-filter: "progid:DXImageTransform.Microsoft.Light()";
            filter: progid:DXImageTransform.Microsoft.Light();
            left: 0;
            position: absolute;
            top: 0;
        }
        /* NOTE: you'll need to use script for hovering support on IE6 */
        #image:hover #yellow {
            display: block;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            document.getElementById('yellow').filters.item("DXImageTransform.Microsoft.Light").addAmbient(255, 255, 0, 100);
        }
    </script>
</head>

<body>
    <div id="image">
        <img src="http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg" alt="">
        <div id="yellow">
            <div id="grayscale">
                <img src="http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg" alt="">
            </div>
        </div>
    </div>
</body>

</html>

刚看到这条消息,非常感谢!更新版本非常完美,谢谢。 - cstr44
没问题。这是一个有趣的实验,也是学习一点东西的机会。将SVG和IE滤镜解决方案合并为单一解决方案以实现最广泛的兼容性将是有趣的。我没有演示的另一个可能的解决方案是使用画布,但我认为最好不要使用它。画布使流体布局更加困难,并且在IE8中不支持(如果这对您很重要)。保重。 - ifugu
是的,我曾经研究过使用画布,但它似乎对我所需的功能过于复杂。希望当CSS3混合模式在各个浏览器中实现时,它能提供更快捷的替代方案! - cstr44

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