在Android上不准确的HSV转换

use*_*782 6 android colors hsv

我正在尝试创建一个壁纸,并在"android.graphics.color"类中使用HSV转换.当我意识到将具有指定色调(0..360)的创建的HSV颜色转换为rgb颜色(整数)并且将后转换为HSV颜色不会导致相同的色调时,我感到非常惊讶.这是我的代码:

int c = Color.HSVToColor(new float[] { 100f, 1, 1 });
float[] f = new float[3];
Color.colorToHSV(c, f);
alert(f[0]);
Run Code Online (Sandbox Code Playgroud)

我从100度的色调开始,结果是99.76471.我想知道为什么(在我看来)存在相对较大的不准确性.

但更大的问题是,当您再次将该值放入代码中时,新结果会再次降低.

int c = Color.HSVToColor(new float[] { 99.76471f, 1, 1 });
float[] f = new float[3];
Color.colorToHSV(c, f);
alert(f[0]);
Run Code Online (Sandbox Code Playgroud)

如果我从99.76471开始,我得到99.52941.这对我来说是个问题.我在java中使用"java.awt.Color"类做了类似的事情,我没有遇到这些问题.不幸的是,我不能在android中使用这个类.

Nic*_*oso 1

这是一个有趣的问题。由于浮点数精度较低,android 类无法避免这种情况。但是,我在这里找到了用 javascript 编写的类似解决方案。

如果对于您来说定义自己的方法/类来进行转换足够重要,那么这里有一个 Java 转换,它应该可以为您提供更好的精度:

@Size(3)
/** Does the same as {@link android.graphics.Color#colorToHSV(int, float[])} */
public double[] colorToHSV(@ColorInt int color) {
    //this line copied vertabim
    return rgbToHsv((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
}

@Size(3)
public double[] rgbToHsv(double r, double g, double b) {
    final double max = Math.max(r,  Math.max(g, b));
    final double min = Math.min(r, Math.min(g, b));
    final double diff = max - min;
    final double h;
    final double s = ((max == 0d)? 0d : diff / max);
    final double v = max / 255d;
    if (min == max) {
        h = 0d;
    } else if (r == max) {
        double tempH = (g - b) + diff * (g < b ? 6: 0);
        tempH /= 6 * diff;
        h = tempH;
    } else if (g == max) {
        double tempH = (b - r) + diff * 2;
        tempH /= 6 * diff;
        h = tempH;
    } else {
        double tempH = (r - g) + diff * 4;
        tempH /= 6 * diff;
        h = tempH;
    }
    return new double[] { h, s, v };
}
Run Code Online (Sandbox Code Playgroud)

我必须在这里承认我的无知 - 我已经完成了快速转换,但没有时间进行正确的测试。可能有一个更优化的解决方案,但这至少应该让您开始。