htmlcssimage

How can I show only one color channel as greyscale?


On a web application, I have an img tag showing the output of a camera (streams via websocket, but it's not relevant for the scope of this question).

The img shows color data, but I need my users to be able to view the RED / GREEN / BLUE channels separately. At least, I need my users to select if they are going to see color or R/G/B channels.

I can do this using canvas, but I'm not aware of a simple way to perform this, without extracting the RGB values as uint8 array and processing them. Besides, at the moment I don't have a canvas at all, and the img tag has performed flawlessly for my needs up until now.

I was wondering if there is some CSS magic to show the channels, something like filter/greyscale, but greyscale has a fixed conversion that doesnt allow preserving the channels, as far as I can tell.

I have seen the existence of mix-blend-mode, but that doesn't seem to support my use case neither.

Suggestions?

Given the requests for clarification: extracting the Green channel and showing it as a greyscale means that, if I have a pixel in the original image that is full green (#00FF00) I would like it to show up as perfect white (#FFFFFF).

Similarly, if I select the blue channel, a pixel perfectly blue (#0000FF) should become white (#FFFFFF).

Doing greyscale usually performs a weighted blend of channels, so full green (255) becomes something like 190, but full blue becomes a dark shade of grey (say, 30ish).

The precise numbers are not a concern, the problem is to perform a greyscale in such a way that 255 in the selected channel becomes white.


Solution

  • You might use SVG filters:

    figure {
      display: inline-block;
      padding: 1em; margin: .2em;
      border: solid 1px;
    }
    
    img {
      width: 150px
    }
    
    .red {
      filter: url(#red)
    }
    
    .green {
      filter: url(#green)
    }
    
    .blue {
      filter: url(#blue)
    }
    <figure>
      <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/RGB_color_wheel_10.svg/250px-RGB_color_wheel_10.svg.png">
      <figcaption>all</figcaption>
    </figure>
    
    <figure>
      <img class="red" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/RGB_color_wheel_10.svg/250px-RGB_color_wheel_10.svg.png">
      <figcaption>red</figcaption>
    </figure>
    
    <figure>
      <img class="green" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/RGB_color_wheel_10.svg/250px-RGB_color_wheel_10.svg.png">
      <figcaption>green</figcaption>
    </figure>
    
    <figure>
      <img class="blue" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/RGB_color_wheel_10.svg/250px-RGB_color_wheel_10.svg.png">
      <figcaption>blue</figcaption>
    </figure>
    
    <svg>
      <defs>
        <filter id="red">
          <feColorMatrix in="SourceGraphic"
            type="matrix"
            values="1 0 0 0 0
                    1 0 0 0 0
                    1 0 0 0 0
                    0 0 0 1 0"
            result="color" />
        </filter>
        <filter id="green">
          <feColorMatrix in="SourceGraphic"
            type="matrix"
            values="0 1 0 0 0
                    0 1 0 0 0
                    0 1 0 0 0
                    0 0 0 1 0"
            result="color" />
        </filter>
        <filter id="blue">
          <feColorMatrix in="SourceGraphic"
            type="matrix"
            values="0 0 1 0 0
                    0 0 1 0 0
                    0 0 1 0 0
                    0 0 1 1 0"
            result="color" />
        </filter>
      </defs>
    </svg>