Search code examples
javascriptfunctionmathcolors

rgb to greyscale converter


Is there a function that converts rgb colours directly into their true greyscale form?

function rgbToGrayscale(red, green, blue) {
    const gray = []

    /* ---- CONVERSION CODE ---- */

    return gray
}

// color
const rgb = [20, 150, 240]

// grayscale conversion
const gray = rgbToGrayscale(rgb[0], rgb[1], rgb[2]) // [121, 121, 121]

I would greatly appreciate it if anyone can find a simple answer to this problem.


Solution

  • Space efficient one liners here:-

    For the exact same situation as OP (thanks @Joachim):-

    Cheap:

    for(gray=[];gray.length<3;gray.push([0,1,2].reduce((a,i)=>a+rgb[i],0)/3));
    

    Quite Good:

    for(gray=[];gray.length<3;gray.push([.3,.59,.11].reduce((a,v,i)=>a+v*rgb[i],0)/3));
    

    P.S.:

    1. If you are fine with not having IE support (Check support for fill()) for the two above, you can replace for(gray=[];gray.length<3;gray.push with gray=Array(3).fill then remove the last ).

    2. Add Math.round( after gray.push( (or Array(3).fill( if you did 1) and ).toString(16).padStart(2,'0') before the last ) to get it in hex values.


    For c='#rrggbb' to:-

    Grayscale Value:

    gray=[.3,.59,.11].reduce((a,v,i)=>a+v*parseInt(c[2*i+1]+c[2*i+2],16),0)/3;
    

    Grayscale #rrggbb:

    gray='#'+Array(4).join(Math.round([.3,.59,.11].reduce((a,v,i)=>a+v*parseInt(c[2*i+1]+c[2*i+2],16),0)/3).toString(16).padStart(2,'0'));
    

    P.S.: Reminder that grayscale color just has the same rr, gg and bb

    1. Remove v* to disable "Quite Good" Mode (also replace [.3,.59,.11] to [0,1,2] then remove v, (but I use just v* so that I can easily toggle between the two modes))
    2. Add x.length<6?c[i+1]+c[i+1]: after parseInt( to support both '#rrggbb' and '#rgb'
    3. Remove the +1(s) then replace the +2 to a +1 to support 'rrggbb' and 'rgb'
    4. If you're fine without IE support (Check support for repeat()) remove Array(4).join( and replace the last ) with .repeat(3)