Почему этот код JavaScript RGB для HSL не работает?

Я нашел этот сценарий RGB для HSL на http://www.mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - ... Я не могу найти других маленьких приличных. Вопрос в том, что этот код даже не работает. Кто-нибудь знает почему? (Я не знаю немного цветовой математики, но, может быть, она возвращает дополнение?)

function rgbToHsl(r, g, b){
    r /= 255, g /= 255, b /= 255;
    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if(max == min){
        h = s = 0; // achromatic
    }else{
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch(max){
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }

    return [h, s, l];
}

Edit: когда я запускаю rgbToHsl(126,210,22) это дает мне [ .24, .81, .45 ], который является HSL для оранжевый цвет.

2 ответов


результирующий массив HSV должен интерпретироваться как три фракции. Для некоторых программ, Если вы хотите выразить HSV в виде целых чисел, вы умножаете значение " H "на 360, а значения" S "и" V " на 100. Значение HSV, которое вы указываете для вашего зеленого оттенка RGB[126, 210, 22], является HSV [87, 81, 45] в целых числах. Вы можете изменить функцию, чтобы вернуть такие целые числа, если хотите:

function rgbToHsl(r, g, b){
    r /= 255, g /= 255, b /= 255;
    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if(max == min){
        h = s = 0; // achromatic
    }else{
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch(max){
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }

    return [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)];
}

[edit] тем не менее, он все еще дает мне что-то с яркостью ("L" или "V"), которая значительно слишком темно; Gimp говорит, что значение HSV должно быть [90, 80, 82] или в дробных терминах [.20, .80, .82].

[другое редактирование] ну, одна проблема может быть в том, что HSL и HSV-разные схемы ... все еще оглядываюсь.

OK в случае, если кто-то хочет RGB для HSV (как вы видели в Gimp, например) вот версия этого:

function rgbToHsv(r, g, b) {
    var
        min = Math.min(r, g, b),
        max = Math.max(r, g, b),
        delta = max - min,
        h, s, v = max;

    v = Math.floor(max / 255 * 100);
    if ( max != 0 )
        s = Math.floor(delta / max * 100);
    else {
        // black
        return [0, 0, 0];
    }

    if( r == max )
        h = ( g - b ) / delta;         // between yellow & magenta
    else if( g == max )
        h = 2 + ( b - r ) / delta;     // between cyan & yellow
    else
        h = 4 + ( r - g ) / delta;     // between magenta & cyan

    h = Math.floor(h * 60);            // degrees
    if( h < 0 ) h += 360;

    return [h, s, v];
}

функция ниже преобразует RGB цвет в оттенок насыщенности яркости цвета, как Photoshop color picker, результаты находятся в диапазонах:

  • оттенок 0-360 (градусов)
  • насыщенность: 0-100 (%)
  • яркости: 0-100 (%)

Я до сих пор не понимаю, почему люди используют термин HSV (значение насыщенности оттенка) вместо HSB (яркость насыщенности оттенка), в любом случае это вопрос терминологии, результаты же

   //Converts to color HSB object (code from here http://www.csgnetwork.com/csgcolorsel4.html with some improvements)
   function rgb2hsb(r, g, b)
   {    
    r /= 255; g /= 255; b /= 255; // Scale to unity.   
    var minVal = Math.min(r, g, b),
    maxVal = Math.max(r, g, b),
    delta = maxVal - minVal,
    HSB = {hue:0, sat:0, bri:maxVal},
    del_R, del_G, del_B;

    if( delta !== 0 )
    {
        HSB.sat = delta / maxVal;
        del_R = (((maxVal - r) / 6) + (delta / 2)) / delta;
        del_G = (((maxVal - g) / 6) + (delta / 2)) / delta;
        del_B = (((maxVal - b) / 6) + (delta / 2)) / delta;

        if (r === maxVal) {HSB.hue = del_B - del_G;}
        else if (g === maxVal) {HSB.hue = (1 / 3) + del_R - del_B;}
        else if (b === maxVal) {HSB.hue = (2 / 3) + del_G - del_R;}

        if (HSB.hue < 0) {HSB.hue += 1;}
        if (HSB.hue > 1) {HSB.hue -= 1;}
    }

    HSB.hue *= 360;
    HSB.sat *= 100;
    HSB.bri *= 100;

    return HSB;
   }

пример использования:

var hsb = rgb2hsb(126,210,22);
alert("hue = " + hsb.hue + "saturation = " + hsb.sat + "brightness = " + hsb.bri);