0

我正在尝试从我的数据库中获取 HSL 颜色值。目前只存储了一个 RGB 值。假设我有单独的 rgb 列:red green blue,每个列都有一个 0-255 的数值。

目标结果将是结果集中的色调饱和度亮度,由 rgb 值计算得出。我已经看到了很多计算,但它们似乎都不够容易在查询中完成?或者我对 SQL 的了解不够深入,不知道如何将 switch 语句之类的东西移植到 SQL 中。

我发现的最好的转换示例在这里:如何获得#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];
}

但是我完全不知道如何在 SQL 中执行类似的计算。

在它不能完全正常工作之后(上面的代码示例与我在维基百科上看到的色调转换不正确,以及我需要 0-360 度而不是 0 到 1 之间的色调)我已经开始了使用 Arth 的解决方案并解决了这个问题,我决定事先在 r,g,b 上使用 /255,因为从上面的代码示例中更容易理解:

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
4

1 回答 1

2

这绝对是一场噩梦,未经测试,但我试了一下:

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

总之,您最好选择 RGB 值并在应用程序级别运行转换!

于 2014-07-29T15:53:06.490 回答