skip to Main Content

I’ve done this in the past and I know it exists, but for some reason I don’t find it right now (wasted couple of hours with no success).

I want to mimic the Photoshop RGB levels via CSS.

On the following image I changed the middle value from 1 to 0.5.

enter image description here

I wanna get the same effect (or at least as close as possible) with CSS.

I’ve tried with the following code: https://jsfiddle.net/txwu3so5/

I need to find some replacement code to get that effect. The actual code affects the white color (I don’t want that).

<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
.img_02 {
    filter: url(#level-50); 
}
</style>
</head>

<body>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;height:0;">
    <defs>
        <filter id="level-50" x="0" y="0">
            <!-- begin of code to replace -->
            <feColorMatrix type="matrix" values="
                0.5 0 0 0 0
                0 0.5 0 0 0
                0 0 0.5 0 0
                0 0   0 1 0"
            />
            <!-- end of code to replace -->
        </filter>
    </defs>
</svg>

<img class="img_01" src="https://image.ibb.co/kzz41Q/image.png" />
<br /><br />
<img class="img_02" src="https://image.ibb.co/kzz41Q/image.png" />

</body>

</html>

In Photoshop I usually change from 1 to different values, for example: 0.75, 0.5, etc. I want to mimic this somehow with CSS. I remembered I used a code very similar to the above one, the only thing that needs to be changed is the replacement code.

[EDIT 1]

This is part of another problem. It is a requirement to use the SVG filter tag.

2

Answers


  1. You are basically updating the gamma of the image here. There is a built-in filter component in SVG to do that.

    <feComponentTransfer type="gamma" ...>
    

    See demo below.

    Note: the filter doesn’t update properly on Chrome, so try this demo with Firefox instead

    var slider = document.getElementById("slider");
    var gamma = document.getElementById("gamma");
    var gammaR = document.getElementById("gammaR");
    var gammaG = document.getElementById("gammaG");
    var gammaB = document.getElementById("gammaB");
    
    slider.addEventListener("input", function(evt) {
    
      var sliderValue = evt.target.value;
      gamma.textContent = sliderValue;
      gammaR.setAttribute("exponent", sliderValue);
      gammaG.setAttribute("exponent", sliderValue);
      gammaB.setAttribute("exponent", sliderValue);
    
    });
    .img_02 {
        filter: url(#level-50); 
    }
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;height:0;">
        <defs>
            <filter id="level-50" x="0" y="0">
                <!-- begin of code to replace -->
                <feComponentTransfer>
                    <feFuncR type="gamma" exponent="2.2" id="gammaR"/>
                    <feFuncG type="gamma" exponent="2.2" id="gammaG"/>
                    <feFuncB type="gamma" exponent="2.2" id="gammaB"/>
                </feComponentTransfer>
                <!-- end of code to replace -->
            </filter>
        </defs>
    </svg>
    
    <img class="img_01" src="https://image.ibb.co/kzz41Q/image.png" />
    <img class="img_02" src="https://image.ibb.co/kzz41Q/image.png" />
    
    <br/>
    <input id="slider" type="range" min="0" max="4" step="0.1" value="1"/>
    <p id="gamma"></p>
    Login or Signup to reply.
  2. To fully duplicate the RGB levels capability from Photoshop, you’d need three filter components: an feComponentTransfer/gamma and two feComponentTransfer/tables. If you’re just adjusting the middle pivot value as above, you just need the first feComponentTranfer. To read more on how ComponentTransfers work – please see the webplatform docs (although they’ve started to rot a little.

    <filter id="RGBlevels" color-interpolation-filters="sRGB">
    
     <!-- set the value of the exponent to 1/[middle pivot input value] you'd use in Photoshop -->
    
      <feComponentTransfer>
          <feFuncR type="gamma" exponent="2"/>
          <feFuncG type="gamma" exponent="2"/>
          <feFuncB type="gamma" exponent="2"/>
      </feComponentTransfer>
    
     <!-- this primitive changes the start and end input values by specifying a new color curve. The values below, for example, set the start value to rgb(76.5,76.5,76.5) and the end value to rgb(204,204,204) -->
    
      <feComponentTransfer>
          <feFuncR type="table" tableValues="0 0 0 0 .2 .4 .6 .8 1 1 1"/>
          <feFuncG type="table" tableValues="0 0 0 0 .2 .4 .6 .8 1 1 1"/>
          <feFuncB type="table" tableValues="0 0 0 0 .2 .4 .6 .8 1 1 1"/>
      </feComponentTransfer>
    
     <!-- this primitive changes the output values to rgb(25.5,25.5, 25.5) <-> rgb(229.5,229.5,229.5) -->
      <feComponentTransfer>
          <feFuncR type="table" tableValues=".1 .9"/>
          <feFuncG type="table" tableValues=".1 .9"/>
          <feFuncB type="table" tableValues=".1 .9"/>
      </feComponentTransfer>
    </filter>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search