安卓如何在RGB和HSV之间转换?

7

有人能解释一下为什么从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)
4个回答

7

如果有人想在 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)


5
最终我找到了解决方案。在安卓实现的android.graphics.Color.RGBToHSV中似乎存在奇怪的近似值。这个近似值恰好是色调,该实现中色调范围从0°到360°。
我找到了java.awt.Color.RGBtoHSB代码,其中色调范围从0.0f到1.0f,转换效果良好。因此这不是浮点精度错误,而是实现错误,事实上通过将Hue * 360f相乘,我得到了正确的HSV色调值。

1
float[] hsv = new float[3];

我想这已经足够回答你的问题了,转换结果是在HSV范围内,范围为[0.0, 1.0],因此您正在处理有限精度,因此将其转换回来不会给出完全相同的值。

我也认为原因是这样。你知道其他精确转换的方法吗? - Marco Di Scala

-3

使用以下方法进行修复:

    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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接