3

I have working CSS filters on the <img /> elements as I want to.

eg.

filter: brightness(1) contrast(67%) saturate(250%) grayscale(0%) invert(0%) hue-rotate(330deg) sepia(40%) blur(0px);

My gol is to apply the same filter properties to the <image /> tag inside SVG file.

However things like

<g style="-webkit-filter: contrast(67%) saturate(250%);">
    <image xlink:href="image.jpg" />
</g>

or

<image xlink:href="image.jpg" style="-webkit-filter: contrast(67%) saturate(250%) sepia(40%)"/>

does not work.

So most likely I have to combine CSS filters as SVG filters.

On webplatform.org I found SVS's represnetation of particular CSS filter effects, eg:

then I have tried to combine generated filters with feMerge.

<filter id="clip_1-filter-90117969876336">
    <feComponentTransfer in="SourceGraphic" result="brightness-filter">
      <feFuncR type="linear" slope="22"></feFuncR>
      <feFuncG type="linear" slope="22"></feFuncG>
      <feFuncB type="linear" slope="22"></feFuncB>
    </feComponentTransfer>

    <feComponentTransfer in="brightness-filter" result="contrast-filter">
      <feFuncR type="linear" slope="-15" intercept="7"></feFuncR>
      <feFuncG type="linear" slope="-15" intercept="7"></feFuncG>
      <feFuncB type="linear" slope="-15" intercept="7"></feFuncB>
    </feComponentTransfer>

    <feColorMatrix in="contrast-filter" result="grayscale-filter" type="matrix" values="
       1 0 0 0 0
       0 1 0 0 0
       0 0 1 0 0
       0 0 0 1 0"></feColorMatrix>

    <feComponentTransfer in="SourceGraphic" result="invert-filter">
      <feFuncR type="table" tableValues="0 1"></feFuncR>
      <feFuncG type="table" tableValues="0 1"></feFuncG>
      <feFuncB type="table" tableValues="0 1"></feFuncB>
    </feComponentTransfer>

    <feMerge>
      <feMergeNode in="grayscale-filter"></feMergeNode>
    </feMerge>
    </filter>

However the results are far from expected.

What is the proper way of translating CSS filters to the SVG?

2
  • 3
    The CSS filters spec has SVG equivalents to each CSS filter: w3.org/TR/filter-effects-1/#grayscaleEquivalent Commented Apr 18, 2016 at 11:41
  • 2
    Michal - I notice that you have a track record of not accepting any answers to your questions. Were you aware that it's good community behavior to do so by clicking the checkmark under the question you want to accept. Commented Apr 28, 2016 at 15:25

2 Answers 2

3

Your filter looks mostly correct, except I suspect there is a typo in your feComponentTransfer in attribute. I think you probably meant:

<feComponentTransfer in="grayscale-filter" result="invert-filter">

Note that you don't need to use result and in if the input to each stage is the output of the last one.

Also, the final feMerge is not needed if there is just the one node.

<svg width="5cm" height="5cm" viewBox="0 0 500 500">
  <defs>
  <filter id="clip_1-filter-90117969876336">
    <feComponentTransfer in="SourceGraphic">
      <feFuncR type="linear" slope="22"></feFuncR>
      <feFuncG type="linear" slope="22"></feFuncG>
      <feFuncB type="linear" slope="22"></feFuncB>
    </feComponentTransfer>

    <feComponentTransfer>
      <feFuncR type="linear" slope="-15" intercept="7"></feFuncR>
      <feFuncG type="linear" slope="-15" intercept="7"></feFuncG>
      <feFuncB type="linear" slope="-15" intercept="7"></feFuncB>
    </feComponentTransfer>

    <feColorMatrix type="matrix" values="
       1 0 0 0 0
       0 1 0 0 0
       0 0 1 0 0
       0 0 0 1 0"></feColorMatrix>

    <feComponentTransfer>
      <feFuncR type="table" tableValues="0 1"></feFuncR>
      <feFuncG type="table" tableValues="0 1"></feFuncG>
      <feFuncB type="table" tableValues="0 1"></feFuncB>
    </feComponentTransfer>
  </filter>
  </defs>

  <image xlink:href="http://lorempixel.com/500/500/"
         width="500" height="500" filter="url(#clip_1-filter-90117969876336)"/>
  <rect fill="none" stroke="blue"  
        x="1" y="1" width="498" height="498"/>
</svg>

1

Your feColorMatrix is currently an identity matrix, not a greyscale filter, and your third feComponentTransfer is also an identity transform (that (0 1) leaves all colors as they are - you probably meant (1 0).)

I don't know what the intention in the last merge is. Do you want to blend the results of the inversion with the greyscale? Or do you want to invert your greyscale.

Take a look at the web platform doc for feColorMatrix and an intro article I wrote for .NET mag to get started. After that I'd suggest reading the spec that Robert links to in the comment.

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