Проблемы с преобразованием HSL в RGB
Я пытаюсь преобразовать значения HSL в RGB, но получаю странные результаты: если значение оттенка составляет около 180, то полученный RGB отрицательно зависит от значения освещенности.
Моя реализация:
public class HSLtoRGB {
private static float hueToRGB(float m1, float m2, float h) {
if(h < 0) {
h += 1.0f;
} else if(h > 1.0f) {
h -= 1.0f;
}
if((h * 6) < 1) {
return m1 + (m2 - m1) * 6 * h;
} else if((h * 2) < 1) {
return m2;
} else if((h * 3) < 2) {
return m1 + (m2 - m1) * ((2 / 3) - h) * 6;
} else {
return m1;
}
}
public static void main(String[] args) {
float h = 180.0f / 360.0f;
float s = 100.0f / 100.0f;
float l = 38.0f / 100.0f;
float r = 0;
float g = 0;
float b = 0;
if(s == 0.0) {
r = g = b = l;
} else {
float m2 = l < 0.5 ? l * (1 + s) : (l + s) - (l * s);
float m1 = (l * 2) - m2;
r = hueToRGB(m1, m2, h + (1.0f / 3.0f));
g = hueToRGB(m1, m2, h);
b = hueToRGB(m1, m2, h - (1.0f / 3.0f));
}
System.out.printf("%.2f %.2f %.2f -> %.2f %.2f %.2f",
h, s, l,
r, g, b);
}
}
и вывод из вышеперечисленного:
0.50 1.00 0.38 -> 0.00 -2.28 0.76
Я следовал этому алгоритму и проверил многие другие, чтобы получить приведенную выше формулу, в том числе и в документации CSS3:
HOW TO RETURN hsl.to.rgb(h, s, l):
SELECT:
l<=0.5: PUT l*(s+1) IN m2
ELSE: PUT l+s-l*s IN m2
PUT l*2-m2 IN m1
PUT hue.to.rgb(m1, m2, h+1/3) IN r
PUT hue.to.rgb(m1, m2, h ) IN g
PUT hue.to.rgb(m1, m2, h-1/3) IN b
RETURN (r, g, b)
HOW TO RETURN hue.to.rgb(m1, m2, h):
IF h<0: PUT h+1 IN h
IF h>1: PUT h-1 IN h
IF h*6<1: RETURN m1+(m2-m1)*h*6
IF h*2<1: RETURN m2
IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
RETURN m1
1 ответ
Решение
Похоже, виновником является эта строка:
return m1 + (m2 - m1) * ((2 / 3) - h) * 6;
Вы делаете целочисленное деление 2/3
, который будет равен 0
, Простое изменение:
return m1 + (m2 - m1) * ((2.0f / 3.0f) - h) * 6;
кажется, это исправить для меня. Возвращается с одинаковым синим / зеленым 0.76
, что имеет смысл для оттенка 180(голубой).