rgb 到色调的转换不正确
Incorrect rgb to hue convertion
我正在尝试在 Java 中将 rgb 颜色转换为 hsl,我搜索了许多解释如何将 rgb 转换为 hsl 的代码,我现在可以使用饱和度和亮度,但是色相值不正确
我现在正在尝试将 rgb 转换为 hsl 然后再返回。
我使用的 rgb 值是
红色:54
绿色:43
蓝色:21
我得到的 hsl 值是
色调:260
饱和度:44
亮度:15
我试图在 https://www.rapidtables.com/convert/color/rgb-to-hsl.html
将 rgb 值转换为 hsl
我得到的值是
色调:40
饱和度:44.0
亮度:14.7
有谁知道我在将 rgb 转换为 hsl 时做错了什么?
这是我的代码
public static Map<String, Integer> rgbToHsl(Integer red, Integer green, Integer blue){
Float redDouble = ((float)red) / 255.0f;
Float greenDouble = ((float)green) / 255.0f;
Float blueDouble = ((float)blue) / 255.0f;
Float max = Math.max(Math.max(redDouble, greenDouble), blueDouble);
Float min = Math.min(Math.min(redDouble, greenDouble), blueDouble);
Float chroma = max - min;
Float hue = chroma == 0.0f ? 0.0f :
(max == redDouble ? (greenDouble - blueDouble) / chroma :
(max == greenDouble ? 2f + (blueDouble - redDouble) / chroma :
4f + (redDouble - greenDouble) / chroma));
Float lightness = (max + min) * 0.5f;
Float saturation = chroma == 0.0f ? 0.0f : (lightness > 0.5f ? chroma / (2.0f - max - min) : chroma / (max + min));
return Map.ofEntries(
Map.entry("hue", (int) Math.round(hue * 60)),
Map.entry("saturation", (int) Math.round(saturation * 100)),
Map.entry("lightness", (int) Math.round(lightness * 100))
);
}
色相值如果红色最大,忘记模6换算了
根据 IntelliJ 向我展示的内容,它不相信 max == redDouble,即使它们的打印值看起来相同。因此,您的色调嵌套逻辑计算出了错误的部分。我建议你写一些逻辑来弄清楚你是在寻找白色、红色、绿色还是蓝色作为字符串,然后使用带有新颜色字符串的开关块作为你的触发器来决定 return 的值.这将更长,但也可能更具可读性。虽然我是三元运算符的粉丝,但嵌套它们可能会造成混乱。
当你在任何地方使用装箱的 Float
时,Math.max(Math.max(a, b), c)
将拆箱参数 a
、b
和 c
,然后执行计算,然后将它们装回 Float
.
结果将是一个新对象,不等于所有三个 a
、b
和 c
。
因此,身份比较 max == redDouble
和 max == greenDouble
将始终是 false
。
消除盒装类型,到处使用float
s,更快更清晰。
更好:永远不要对任何类型的浮点值使用 ==
或 equals
。例如,请参阅如何使用 here 个额外的布尔标志。布尔值不易受微小舍入误差的影响。
我正在尝试在 Java 中将 rgb 颜色转换为 hsl,我搜索了许多解释如何将 rgb 转换为 hsl 的代码,我现在可以使用饱和度和亮度,但是色相值不正确
我现在正在尝试将 rgb 转换为 hsl 然后再返回。
我使用的 rgb 值是
红色:54 绿色:43 蓝色:21
我得到的 hsl 值是
色调:260 饱和度:44 亮度:15
我试图在 https://www.rapidtables.com/convert/color/rgb-to-hsl.html
将 rgb 值转换为 hsl我得到的值是
色调:40 饱和度:44.0 亮度:14.7
有谁知道我在将 rgb 转换为 hsl 时做错了什么? 这是我的代码
public static Map<String, Integer> rgbToHsl(Integer red, Integer green, Integer blue){
Float redDouble = ((float)red) / 255.0f;
Float greenDouble = ((float)green) / 255.0f;
Float blueDouble = ((float)blue) / 255.0f;
Float max = Math.max(Math.max(redDouble, greenDouble), blueDouble);
Float min = Math.min(Math.min(redDouble, greenDouble), blueDouble);
Float chroma = max - min;
Float hue = chroma == 0.0f ? 0.0f :
(max == redDouble ? (greenDouble - blueDouble) / chroma :
(max == greenDouble ? 2f + (blueDouble - redDouble) / chroma :
4f + (redDouble - greenDouble) / chroma));
Float lightness = (max + min) * 0.5f;
Float saturation = chroma == 0.0f ? 0.0f : (lightness > 0.5f ? chroma / (2.0f - max - min) : chroma / (max + min));
return Map.ofEntries(
Map.entry("hue", (int) Math.round(hue * 60)),
Map.entry("saturation", (int) Math.round(saturation * 100)),
Map.entry("lightness", (int) Math.round(lightness * 100))
);
}
色相值如果红色最大,忘记模6换算了
根据 IntelliJ 向我展示的内容,它不相信 max == redDouble,即使它们的打印值看起来相同。因此,您的色调嵌套逻辑计算出了错误的部分。我建议你写一些逻辑来弄清楚你是在寻找白色、红色、绿色还是蓝色作为字符串,然后使用带有新颜色字符串的开关块作为你的触发器来决定 return 的值.这将更长,但也可能更具可读性。虽然我是三元运算符的粉丝,但嵌套它们可能会造成混乱。
当你在任何地方使用装箱的 Float
时,Math.max(Math.max(a, b), c)
将拆箱参数 a
、b
和 c
,然后执行计算,然后将它们装回 Float
.
结果将是一个新对象,不等于所有三个 a
、b
和 c
。
因此,身份比较 max == redDouble
和 max == greenDouble
将始终是 false
。
消除盒装类型,到处使用float
s,更快更清晰。
更好:永远不要对任何类型的浮点值使用 ==
或 equals
。例如,请参阅如何使用 here 个额外的布尔标志。布尔值不易受微小舍入误差的影响。