2010-12-11 10 views
24

私はパーセント値に応じて色を計算したいと思います:アンドロイドカラーは、2つの色の間にパーセントで基づいていますか?

float percentage = x/total; 
int color; 
if (percentage >= 0.95) { 
    color = Color.GREEN; 
} else if (percentage <= 0.5) { 
    color = Color.RED; 
} else { 
    // color = getColor(Color.Green, Color.RED, percentage); 
} 

は、どのように私はその最後のものを計算することができますか?黄色が50%で表示されても問題ありません。

私はこれを試してみました:

private int getColor(int c0, int c1, float p) { 
    int a = ave(Color.alpha(c0), Color.alpha(c1), p); 
    int r = ave(Color.red(c0), Color.red(c1), p); 
    int g = ave(Color.green(c0), Color.green(c1), p); 
    int b = ave(Color.blue(c0), Color.blue(c1), p); 
    return Color.argb(a, r, g, b); 
} 
private int ave(int src, int dst, float p) { 
    return src + java.lang.Math.round(p * (dst - src)); 
} 

まあ、これは動作しますが、私は灰色の背景にそれらを使用するように私はより多くのlightendている50%前後で色をしたいと思います...どのように私はそれを達成することができますか?

ありがとうございます!

更新日 コメントに示唆されたように私はYUVに変換しようとしました。しかし、私はまだ50%でそれは暗いものと同じ問題を抱えています。 このソリューションでは、私はに5%白の色を追加しました。 float y = ave(...);を計算しないで、ちょうどfloat y = c0.yを取ると少し良いですが、<で20%私はシアンの色を持っています...私はあまり色の形式にはありません: -/ 多分私は何か間違っている計算で?定数は、ウィキペディアから取られた

public class ColorUtils { 

    private static class Yuv { 
     public float y; 
     public float u; 
     public float v; 

     public Yuv(int c) { 
      int r = Color.red(c); 
      int g = Color.green(c); 
      int b = Color.blue(c); 
      this.y = 0.299f * r + 0.587f * g + 0.114f * b; 
      this.u = (b - y) * 0.493f; 
      this.v = (r - y) * 0.877f; 
     } 
    } 

    public static int getColor(int color0, int color1, float p) { 
     Yuv c0 = new Yuv(color0); 
     Yuv c1 = new Yuv(color1); 
     float y = ave(c0.y, c1.y, p); 
     float u = ave(c0.u, c1.u, p); 
     float v = ave(c0.v, c1.v, p); 

     int b = (int) (y + u/0.493f); 
     int r = (int) (y + v/0.877f); 
     int g = (int) (1.7f * y - 0.509f * r - 0.194f * b); 

     return Color.rgb(r, g, b); 
    } 

    private static float ave(float src, float dst, float p) { 
     return src + Math.round(p * (dst - src)); 
    } 
} 
+1

YUVに変換して輝度値を比較したことがありますか? – SRM

+0

はい、私は質問にそれを編集しました...それは同じ問題です。 – Stuck

答えて

4

Ok、yuv、hsvなどに変換してから2時間後...私はあきらめます。中央の色として黄色を使用して明示的にすることで

public class ColorUtils { 
    private static int FIRST_COLOR = Color.GREEN; 
    private static int SECOND_COLOR = Color.YELLOW; 
    private static int THIRD_COLOR = Color.RED; 

    public static int getColor(float p) { 
     int c0; 
     int c1; 
     if (p <= 0.5f) { 
      p *= 2; 
      c0 = FIRST_COLOR; 
      c1 = SECOND_COLOR; 
     } else { 
      p = (p - 0.5f) * 2; 
      c0 = SECOND_COLOR; 
      c1 = THIRD_COLOR; 
     } 
     int a = ave(Color.alpha(c0), Color.alpha(c1), p); 
     int r = ave(Color.red(c0), Color.red(c1), p); 
     int g = ave(Color.green(c0), Color.green(c1), p); 
     int b = ave(Color.blue(c0), Color.blue(c1), p); 
     return Color.argb(a, r, g, b); 
    } 

    private static int ave(int src, int dst, float p) { 
     return src + java.lang.Math.round(p * (dst - src)); 
    } 
} 

、生成された色がとにかく

:-)明るい...誰かが良い他のソリューションを持っている場合、私は感謝:私は今、ちょうどこのようにそれを行いますそれ。

-2

2色の間で直線的に補間する擬似コード関数です。(staying in RGB space)。明快にするためにintの代わりにColorというクラスを使用しています。

bAmountこのような

Color interpolate(Color colorA, Color colorB, float bAmount) { 
    Color colorOut; 
    float aAmount = 1.0 - bAmount; 
    colorOut.r = colorA.r * aAmount + colorB.r * bAmount; 
    colorOut.g = colorA.g * aAmount + colorB.g * bAmount; 
    colorOut.b = colorA.b * aAmount + colorB.b * bAmount; 
    return colorOut; 
} 
+2

彼は "それを試しました"。 –

8

補間が最良HSL or HSV色空間(およびいないYUV)で行われる(補間のために)0と1の間です。あなたは、単に直線的に緑(#00ff00)真ん中の色をランプダウンと同時に赤(#ff0000)を立ち上げた場合は#808000代わりの#ffff00として終わるので

ミッドレンジの色は「泥」に見える理由があります。

代わりに、開始色と同等のHSL(またはHSV)と、終了色と同じものを探します。補間するその色空間、し、各ポイントのRGBに再度変換します。

S及びL(又はV)の値は完全に飽和赤と緑について同じであるので、唯一H(色相)変数は、色のスペクトルの適切な影響を与え、変化します。

+0

はうまくいきます...ありがとうございました:) – mibollma

26

私の$ 0.02、私はこの答えを見つけ、適切な解決策をコーディングしました。 (HSVのチップのAlnitakに感謝!)については

コピー+貼り付け:

private float interpolate(float a, float b, float proportion) { 
    return (a + ((b - a) * proportion)); 
    } 

    /** Returns an interpoloated color, between <code>a</code> and <code>b</code> */ 
    private int interpolateColor(int a, int b, float proportion) { 
    float[] hsva = new float[3]; 
    float[] hsvb = new float[3]; 
    Color.colorToHSV(a, hsva); 
    Color.colorToHSV(b, hsvb); 
    for (int i = 0; i < 3; i++) { 
     hsvb[i] = interpolate(hsva[i], hsvb[i], proportion); 
    } 
    return Color.HSVToColor(hsvb); 
    } 
+0

これはアルファチャンネルを処理しないことに注意してください。 'Color.colorToHSV' docs:" color - 変換するargbの色。アルファ成分は無視されます。 " – tir38

+0

ここでアルファを扱う答えが更新されました:http://stackoverflow.com/a/38536770/1650674 – tir38

+0

青と赤の間を補間すると黄色になりますが、ピンクが必要です。この答えは –

47

あなたは、AndroidのAPIからArgbEvaluatorクラスを使用して試すことができます:http://developer.android.com/reference/android/animation/ArgbEvaluator.html

アルファチャンネルの計算それほどのバグ( http://code.google.com/p/android/issues/detail?id=36158)があること
new ArgbEvaluator().evaluate(0.75, 0x00ff00, 0xff0000); 

注意アルファ値なしの値を使用する必要があります。ここで

+9

+1です。結果をintにキャストする: 'int color =(Integer)new ArgbEvaluator()。evaluate(0.75、0x00ff00、0xff0000);' –

+0

このクラスにはAPIレベル11+が必要です。 –

+1

これにカラーリソースを使用するには、 'R.color.my_color' intの代わりに' ContextCompat.getColor(context、R.color.my_color) 'を使用してください。 –

0

は補間する2つの方法があります:

private static float interpolate(final float a, final float b, final float proportion) { 
    return a + (b - a) * proportion; 
} 

/** Returns an interpoloated color, between <code>a</code> and <code>b</code> */ 
public static int interpolateColorHsv(final int a, final int b, final float proportion) { 
    final float[] hsva = new float[3]; 
    final float[] hsvb = new float[3]; 
    Color.colorToHSV(a, hsva); 
    Color.colorToHSV(b, hsvb); 
    for (int i = 0; i < 3; ++i) { 
     hsvb[i] = interpolate(hsva[i], hsvb[i], proportion); 
    } 
    return Color.HSVToColor(hsvb); 
} 

public static int interpolateRGB(final int colorA, final int colorB, final float bAmount) { 
    final float aAmount = 1.0f - bAmount; 
    final int red = (int) (Color.red(colorA) * aAmount + Color.red(colorB) * bAmount); 
    final int green = (int) (Color.green(colorA) * aAmount + Color.green(colorB) * bAmount); 
    final int blue = (int) (Color.blue(colorA) * aAmount + Color.blue(colorB) * bAmount); 
    return Color.rgb(red, green, blue); 
} 
1

私はちょうど同様にアルファチャンネルを処理するためにMark Renouf's answerを更新したい:

private float interpolate(float a, float b, float proportion) { 
    return (a + ((b - a) * proportion)); 
} 

/** 
* Returns an interpolated color, between <code>a</code> and <code>b</code> 
* proportion = 0, results in color a 
* proportion = 1, results in color b 
*/ 
private int interpolateColor(int a, int b, float proportion) { 

    if (proportion > 1 || proportion < 0) { 
     throw new IllegalArgumentException("proportion must be [0 - 1]"); 
    } 
    float[] hsva = new float[3]; 
    float[] hsvb = new float[3]; 
    float[] hsv_output = new float[3]; 

    Color.colorToHSV(a, hsva); 
    Color.colorToHSV(b, hsvb); 
    for (int i = 0; i < 3; i++) { 
     hsv_output[i] = interpolate(hsva[i], hsvb[i], proportion); 
    } 

    int alpha_a = Color.alpha(a); 
    int alpha_b = Color.alpha(b); 
    float alpha_output = interpolate(alpha_a, alpha_b, proportion); 

    return Color.HSVToColor((int) alpha_output, hsv_output); 
} 
5

このスレッドのソリューションのいくつかは、私のために動作しませんでした、私は別のソリューションを作成します。たぶんそれは誰かにとって役に立ちます。

/** 
* Get the color between two given colors 
* @param colorStart int color start of degradate 
* @param colorEnd int color end of degradate 
* @param percent int percent to apply (0 to 100) 
* @return int color of degradate for given percent 
*/ 
public static int getColorOfDegradate(int colorStart, int colorEnd, int percent){ 
    return Color.rgb(
      getColorOfDegradateCalculation(Color.red(colorStart), Color.red(colorEnd), percent), 
      getColorOfDegradateCalculation(Color.green(colorStart), Color.green(colorEnd), percent), 
      getColorOfDegradateCalculation(Color.blue(colorStart), Color.blue(colorEnd), percent) 
    ); 
} 

private static int getColorOfDegradateCalculation(int colorStart, int colorEnd, int percent){ 
    return ((Math.min(colorStart, colorEnd)*(100-percent)) + (Math.max(colorStart, colorEnd)*percent))/100; 
} 
+0

素晴らしい!完璧に動作します –

関連する問題