Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android上的HSV转换不准确_Android_Colors_Hsv - Fatal编程技术网

Android上的HSV转换不准确

Android上的HSV转换不准确,android,colors,hsv,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]); 我从100

我正在尝试创建一张壁纸,并在“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]);
我从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]);
如果我从99.76471开始,我得到99.52941。这对我来说是个问题。
我在java中对“java.awt.Color”类做了类似的事情,我没有遇到这些问题。不幸的是,我不能在android中使用这个类。

这是一个有趣的问题。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 };
}
@Size(3)
/**与{@link android.graphics.Color#colorToHSV(int,float[])相同*/
公共双[]色ToHSV(@ColorInt-color){
//这行复制了vertabim
返回rgbToHsv((颜色>>16)和0xFF,(颜色>>8)和0xFF,颜色和0xFF);
}
@尺寸(3)
公共双[]rgbToHsv(双r、双g、双b){
最终双最大值=数学最大值(r,数学最大值(g,b));
最后的双最小值=Math.min(r,Math.min(g,b));
最终双差=最大-最小;
最后双h;
最终双s=((最大==0d)?0d:diff/max);
最终双v=最大值/255d;
如果(最小值==最大值){
h=0d;
}否则,如果(r==最大值){
双节律=(g-b)+diff*(g

我不得不承认我的无知——我已经做了快速转换,没有时间进行适当的测试。可能会有一个更为优化的解决方案,但这至少应该让您开始。

我认为这是一个在16位和32位整数之间使用不同转换的情况,但这可能有点离谱。我记得几年前遇到了声音文件和从字节数组转换的问题。最后我把数字四舍五入到最接近的整数。我支持戴夫的观点。一件可能有用的事情是,请注意原始值100和舍入结果99.76471之间的差值为60/255,255=2^8-1(通常在8位上存储rgb值)。99.76471和99.52941也是如此。我没有一个完整的理论,但基本的算术似乎出了问题。看起来更精确的双精度并不能解决我的问题,因为它仍然是四舍五入到一个整数,可能有一个问题,我没有得到相同的值