2015-12-27 36 views
6

我正在嘗試創建壁紙並在「android.graphics.color」類中使用HSV轉換。當我意識到將創建的具有指定色相(0..360)的HSV顏色轉換爲rgb顏色(整數)並將其轉換爲HSV顏色不會導致相同的色調時,我感到非常驚訝。這是我的代碼:Android上的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中使用這個類。

+0

我相信*這是一個16位和32位整數之間使用不同轉換的情況,但這可能會失敗。我記得幾年前,我遇到了一個聲音文件和字節數組轉換問題。最後我只是將數字四捨五入到最接近的整數。 – dave

+1

我支持戴夫的想法。可能有用的一件事是注意到原始值100與99.76471的四捨五入結果之間的差異是60/255,並且255 = 2^8-1(將rgb值存儲在8位上是相當常見的) 。 99.76471和99.52941也是如此。我沒有一個完整的理論,但似乎基本的算術出錯了。 – elias

回答

1

這是一個有趣的問題。由於浮點精度較低,所以android類無法避免。但是,我發現了一個用javascript here編寫的類似解決方案。

如果它夠重要的是你要定義你自己的方法/類做轉換,這裏是一個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 }; 
} 

我必須在這裏承認無知 - 我做了快速轉換,沒有時間正確測試。可能會有一個更優化的解決方案,但這至少會讓你開始。

+0

好吧,看起來更精確的double沒有解決我的問題,因爲它仍然是一個整數,可能有問題,我沒有得到相同的值 – user2957782