1

I'm trying to simulate mix-blend-mode:exclusion blending mode with only SVG filters. The docs say exclusion is a substraction of darker color from lighter, in other words, greater color component value minus smaller color component value. Is there any way to simulate this logic using SVG filters? The original image is:

enter image description here

The filtered image would be:

enter image description here

The color to exclude is #3a0339

I'm bringing some code snippets for your convenience:

svg {
  width: 0;
  height: 0;
}
.myFilter {
  filter: url(#myFilter);
}
<svg>
<defs>
<filter id="myFilter" x="0" y="0" width="100%" height="100%">
  <feFlood result="fill" flood-color="#3a0339" flood-opacity="1">
  </feFlood>
<feComposite operator="arithmetic" in="SourceGraphic" in2="fill" k1="0" k2="0.5" k3="0.5" k4="0"/>
 </filter>
</defs>
</svg>
<img class="myFilter" src="https://i.sstatic.net/ux2FT.png">

6
  • 1
    I don't think this is possible. You can get close by combining two feBlends (screen and multiply), but the final composition requires one be subtracted from the other. And I don't think there is a way to subtract two colours without zeroing out the alpha channel. Commented May 16, 2017 at 15:25
  • @PaulLeBeau so all calculations actually involve alpha channel same way other channels are processed? Commented May 16, 2017 at 17:12
  • 1
    To subtract them, you would need to use feComposite, but that also subtracts the alphas, so they cancel out (ie. 1-1=0). Leaving you with an invisible result. Commented May 16, 2017 at 17:41
  • @PaulLeBeau But there's a way to extract alpha channel? Using 'feFuncA' or 'SourceAlpha'. If I could somehow zro out alpha after extraction and then add it back later? Commented May 16, 2017 at 18:48
  • 1
    That doesn't work. Filter primitive results are premultiplied. So if you zero out the alpha, the colour components get zeroed as well. It doesn't matter anyway, I have found a solution,See my answer. Commented May 16, 2017 at 18:59

1 Answer 1

2

The Filter Effects module updated the definition of <feBlend>. In addition to the values of mode defined in the SVG 1.1 spec, you can now use all of the extra modes defined by the Compositing and Blending specification.

That includes "exclusion", so as long as you are in a browser environment, you can actually do what you want quite easily. The following works in Firefox and Chrome. I haven't checked any other browsers.

svg {
  width: 0;
  height: 0;
}
.myFilter {
  filter: url(#myFilter);
}
.myFilter2 {
  mix-blend-mode: exclusion;
}
.mix-bg {
  background-color: #3a0339;
  display: inline-block;
}
.mix-bg IMG {
  display: block;
}
<svg>
  <defs>
    <filter id="myFilter" x="0" y="0" width="100%" height="100%"
            color-interpolation-filters="sRGB">
      <feFlood flood-color="#3a0339" result="flood"/>
      <feBlend mode="exclusion" in="flood" in2="SourceGraphic"/>
    </filter>
  </defs>
</svg>

<img class="myFilter" src="https://i.sstatic.net/ux2FT.png">

<div class="mix-bg">
  <img class="myFilter2" src="https://i.sstatic.net/ux2FT.png">
</div>

1
  • Credit goes to @AmeliaBR for reminding me of this change. Commented May 16, 2017 at 19:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.