Search code examples
c#colorspixelspectrogram

Map a value [0.0-1.0] to color gain


I need to translate values from 0.0 to 1.0 to their color representations (each value is a pixel). I am making a spectrogram, so the higher the value the brightest the pixel should be (as in the below image).

How can I do this? I am working in C# but a universally applicable solution is fine too.

Example:

enter image description here


Solution

  • This answer should not only show you how to create a color from an single float value, but the output shall resemble the shown intensity scale pretty well.

    private float LinearStep(float x, float start, float width = 0.2f)
    {
        if (x < start)
            return 0f;
        else if (x > start+width)
            return 1;
        else
            return (x-start) / width;
    }
    
    private float GetRedValue(float intensity)
    {
        return LinearStep(intensity, 0.2f);
    }
    
    private float GetGreenValue(float intensity)
    {
        return LinearStep(intensity, 0.6f);
    }
    
    private float GetBlueValue(float intensity)
    {
        return LinearStep(intensity, 0f)
        - LinearStep(intensity, 0.4f)
        + LinearStep(intensity, 0.8f);
    }
    
    private Color getColor(float intensity)
    {
        return Color.FromArgb(255,
            (int)(255*GetRedValue(intensity)),
            (int)(255*GetGreenValue(intensity)),
            (int)(255*GetBlueValue(intensity))
        );
    }
    

    I did this in notepad++, so it's not tested. But you should get the idea ;-)

    Of course you can use this to create a lookup table. That's entirely up to you ;-)


    As I cannot put this image in the comments, here is the process how to get to this solution: figure 1

    1. Identify the "pure" colors. by this I mean the ones in the 8 colors palette where every component is either 255 or zero.
    2. Draw the dashed lines. You know the rgb values at these points.
    3. Interpolate linearly.

    Step 3 is done by the LinearStep() function in the code, one call for each slope. Ascending slopes are added, descending slopes are subtracted. If you are unsure about this, try to do this with the original color map. I hope you can take it from here :-)