skip to Main Content

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?

Edit

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.

2

Answers


  1. Have you tried mix-blend-mode: multiply; while setting the color of what’s behind the image to either the R,G or B color?

    Something like this:

    .example-container-rgb {
      display: inline-block;
      background-color: #fff;
    }
    
    .example-container-r {
      display: inline-block;
      background-color: #f00;
    }
    
    .example-container-g {
      display: inline-block;
      background-color: #0f0;
    }
    
    .example-container-b {
      display: inline-block;
      background-color: #00f;
    }
    <div class="example-container-rgb">
          <img id="example-element" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="200" style="mix-blend-mode: multiply;">
    </div>
    <div class="example-container-r">
          <img id="example-element" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="200" style="mix-blend-mode: multiply;">
    </div>
    <div class="example-container-g">
          <img id="example-element" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="200" style="mix-blend-mode: multiply;">
    </div>
    <div class="example-container-b">
          <img id="example-element" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="200" style="mix-blend-mode: multiply;">
    </div>
    Login or Signup to reply.
  2. You can make a structure like a

    <div class="image-container">
        <img id="original" src="your-image-source.jpg" alt="Camera Stream" />
        <img id="red-channel" src="your-image-source.jpg" alt="Red Channel" />
        <img id="green-channel" src="your-image-source.jpg" alt="Green Channel" />
        <img id="blue-channel" src="your-image-source.jpg" alt="Blue Channel" />
    </div>
    

    And use a CSS

        .image-container {
        position: relative;
        width: 640px; /* Set to your image width */
        height: 480px; /* Set to your image height */
    }
    
    .image-container img {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover; /* Ensures the image covers the container */
    }
    
    #red-channel {
        filter: grayscale(1) brightness(0) contrast(0) sepia(1) hue-rotate(0deg);
    }
    
    #green-channel {
        filter: grayscale(1) brightness(0) contrast(0) sepia(1) hue-rotate(120deg);
    }
    
    #blue-channel {
        filter: grayscale(1) brightness(0) contrast(0) sepia(1) hue-rotate(240deg);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search