android 从 rgb 转换为 hsv,反之亦然
android convert from rgb to hsv and viceversa
有人可以解释为什么从 rgb 到 hsv 的转换在从 hsv 转换回 rgb 时不会给出相同的结果吗?
int color = Color.rgb(206, 43, 55);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
System.out.println(red + ", " + green + ", " + blue);
//prints: 206, 43, 55 (as expected)
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];
int outputColor = Color.HSVToColor(hsv);
red = Color.red(outputColor);
green = Color.green(outputColor);
blue = Color.blue(outputColor);
System.out.println(red + ", " + green + ", " + blue);
//prints: 206, 42, 54 (green and blue are changed)
float[] hsv = new float[3];
我想这足以回答您的问题,转换的结果是范围为 [0.0, 1.0]
的 HSV,因此您处理的是有限精度,因此将其转换回来不会给出完全相同的值。
我终于找到了解决办法。
在 android.graphics.Color.RGBToHSV
的 android 实现中似乎有一个奇怪的近似值。
近似值恰好是此实现中从 0° 到 360° 的色调。
我找到了 java.awt.Color.RGBtoHSB 的代码,其中 HUE 从 0.0f 变为 1.0f,并且转换效果很好。所以不是浮点精度错误而是实现错误,事实上通过乘以 Hue * 360f
我得到正确的 HSV 色调值。
使用此修复:
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];
// i delete this part
/*int outputColor = Color.HSVToColor(hsv);
red = Color.red(outputColor);
green = Color.green(outputColor);
blue = Color.blue(outputColor);*/
//use only this to get correct values (HSV)
System.out.println(hue + ", " + sat+ ", " + val);
如果有人查看 Kotlin 语言中从 RGB 到 HSV 的转换,反之亦然:
// define array and color
var hsv = FloatArray(3)
var currentColor = Color.rgb(206, 43, 55);
// RGB to HSV
Color.colorToHSV(currentColor, hsv)
// hsv[0] --> hue
// hsv[1] --> saturation
// hsv[2] --> value
// HSV to RGB
currentColor = Color.HSVToColor(hsv)
// assign red, green and blue
r = Color.red(currentColor)
g = Color.green(currentColor)
b = Color.blue(currentColor)
有人可以解释为什么从 rgb 到 hsv 的转换在从 hsv 转换回 rgb 时不会给出相同的结果吗?
int color = Color.rgb(206, 43, 55);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
System.out.println(red + ", " + green + ", " + blue);
//prints: 206, 43, 55 (as expected)
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];
int outputColor = Color.HSVToColor(hsv);
red = Color.red(outputColor);
green = Color.green(outputColor);
blue = Color.blue(outputColor);
System.out.println(red + ", " + green + ", " + blue);
//prints: 206, 42, 54 (green and blue are changed)
float[] hsv = new float[3];
我想这足以回答您的问题,转换的结果是范围为 [0.0, 1.0]
的 HSV,因此您处理的是有限精度,因此将其转换回来不会给出完全相同的值。
我终于找到了解决办法。
在 android.graphics.Color.RGBToHSV
的 android 实现中似乎有一个奇怪的近似值。
近似值恰好是此实现中从 0° 到 360° 的色调。
我找到了 java.awt.Color.RGBtoHSB 的代码,其中 HUE 从 0.0f 变为 1.0f,并且转换效果很好。所以不是浮点精度错误而是实现错误,事实上通过乘以 Hue * 360f
我得到正确的 HSV 色调值。
使用此修复:
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];
// i delete this part
/*int outputColor = Color.HSVToColor(hsv);
red = Color.red(outputColor);
green = Color.green(outputColor);
blue = Color.blue(outputColor);*/
//use only this to get correct values (HSV)
System.out.println(hue + ", " + sat+ ", " + val);
如果有人查看 Kotlin 语言中从 RGB 到 HSV 的转换,反之亦然:
// define array and color
var hsv = FloatArray(3)
var currentColor = Color.rgb(206, 43, 55);
// RGB to HSV
Color.colorToHSV(currentColor, hsv)
// hsv[0] --> hue
// hsv[1] --> saturation
// hsv[2] --> value
// HSV to RGB
currentColor = Color.HSVToColor(hsv)
// assign red, green and blue
r = Color.red(currentColor)
g = Color.green(currentColor)
b = Color.blue(currentColor)