Pregunta

Estoy tratando de obtener un valor de color HSL de mi base de datos. Actualmente solo hay un valor RGB almacenado. Supongamos que obtuve columnas separadas para RGB: azul verde azul con un valor número 0-255 en ellos cada uno.

El resultado de destino sería una ligereza de saturación de tono en el resultado, calculada a partir de los valores RGB. He visto muchos cálculos, ¡pero ninguno de ellos parece ser lo suficientemente fácil de hacer en una consulta? O no soy lo suficientemente profundamente en SQL en general para saber cómo abrir algo como una declaración de conmutación a SQL.

El mejor ejemplo para la conversión que he encontrado está aquí: ¿Cómo obtiene el tono de un color #xxxxxx?

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];
}

Pero estoy completamente perplejo por una respuesta sobre cómo hacer algo como este cálculo en SQL.

Después de que no funciona correctamente (la muestra de código anterior es incorrecta de lo que puedo ver en Wikipedia para la conversión del tono, así como necesitaba el tono en grados completos 0-360 en lugar de entre 0 y 1) i He comenzado con la solución de Arth y llegó a esto, decidí a A / 255 en R, G, b de antemano porque eso es más fácil de seguir desde la muestra de código anterior:

CASE 
  WHEN r>=g AND g>=b  THEN ((g-b)/(r-b))*60
  WHEN g>r AND r>=b THEN (2-(r-b)/(g-b))*60
  WHEN g>=b AND b>r THEN (2+(b-r)/(g-r))*60
  WHEN b>g AND g>r THEN (4-(g-r)/(b-r))*60
  WHEN b>r AND r>=g THEN (4+(r-g)/(b-g))*60
  WHEN r>=b AND b>g THEN (6-(b-g)/(r-g))*60
END h,
CASE 
  WHEN r=g  AND g=b  THEN 0
  WHEN r>=g AND g>=b AND  (r-b)>0.5 THEN (r-b)/(2-r-b)          
  WHEN r>=g AND g>=b THEN (r-b)/(r+b)
  WHEN r>=g AND b>g  AND  (r-g)>0.5 THEN (r-g)/(2-r-g)
  WHEN r>=g AND b>g  THEN (r-g)/(r+g) 
  WHEN g>=r AND r>=b AND  (g-b)>0.5 THEN (g-b)/(2-g-b) 
  WHEN g>=r AND r>=b THEN (g-b)/(g+b)
  WHEN g>=r AND b>r  AND  (g-r)>0.5 THEN (g-r)/(2-g-r) 
  WHEN g>=r AND b>r  THEN (g-r)/(g+r)
  WHEN b>=r AND r>=g AND  (b-g)>0.5 THEN (b-g)/(2-b-g) 
  WHEN b>=r AND r>=g THEN (b-g)/(b+g)
  WHEN b>=r AND g>r  AND  (b-r)>0.5 THEN (b-r)/(2-b-r) 
  WHEN b>=r AND g>r  THEN (b-r)/(b+r)
END s,
CASE 
  WHEN r=g  AND g=b  THEN r
  WHEN r>=g AND g>=b THEN (r+b)/2
  WHEN r>=g AND b>g  THEN (r+g)/2
  WHEN g>=r AND r>=b THEN (g+r)/2
  WHEN g>=r AND b>r  THEN (g+b)/2
  WHEN b>=r AND r>=g THEN (b+g)/2
  WHEN b>=r AND g>r  THEN (b+r)/2
END l

¿Fue útil?

Solución

Es una pesadilla absoluta y no se ha probado, pero he tenido una oportunidad:

SELECT 
    CASE 
      WHEN r=g  AND g=b  THEN 0
      WHEN r>=g AND g>b  THEN ((g-b)/(r-b))/6
      WHEN r>=g AND b>=g THEN ((g-b)/(r-g)+6)/6
      WHEN g>=r AND r>=b THEN ((b-r)/(g-b)+2)/6
      WHEN g>=r AND b>r  THEN ((b-r)/(g-r)+2)/6
      WHEN b>=r AND r>=g THEN ((r-g)/(b-g)+4)/6
      WHEN b>=r AND g>r  THEN ((r-g)/(b-r)+4)/6
    END h,
    CASE 
      WHEN r=g  AND g=b  THEN 0
      WHEN r>=g AND g>=b AND  (r-b)>0.5*255 THEN (r-b)/(510-r-b)          
      WHEN r>=g AND g>=b THEN (r-b)/(r+b)
      WHEN r>=g AND b>g  AND  (r-g)>0.5*255 THEN (r-g)/(510-r-g)
      WHEN r>=g AND b>g  THEN (r-g)/(r+g) 
      WHEN g>=r AND r>=b AND  (g-b)>0.5*255 THEN (g-b)/(510-g-b) 
      WHEN g>=r AND r>=b THEN (g-b)/(g+b)
      WHEN g>=r AND b>r  AND  (g-r)>0.5*255 THEN (g-r)/(510-g-r) 
      WHEN g>=r AND b>r  THEN (g-r)/(g+r)
      WHEN b>=r AND r>=g AND  (b-g)>0.5*255 THEN (b-g)/(510-b-g) 
      WHEN b>=r AND r>=g THEN (b-g)/(b+g)
      WHEN b>=r AND g>r  AND  (b-r)>0.5*255 THEN (b-r)/(510-b-r) 
      WHEN b>=r AND g>r  THEN (b-r)/(b+r)
    END s,
    CASE 
      WHEN r=g  AND g=b  THEN r/255
      WHEN r>=g AND g>=b THEN (r+b)/510
      WHEN r>=g AND b>g  THEN (r+g)/510
      WHEN g>=r AND r>=b THEN (g+r)/510
      WHEN g>=r AND b>r  THEN (g+b)/510
      WHEN b>=r AND r>=g THEN (b+g)/510
      WHEN b>=r AND g>r  THEN (b+r)/510
    END l
FROM table1

En conclusión, ¡probablemente esté mejor seleccionando los valores de RGB y ejecutando la conversión en el nivel de la aplicación!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top