2011-01-12 37 views
9

Tengo una configuración de usuario donde pueden elegir los colores de las alertas. la alerta es el color de fondo de un texto o botón. Pero el problema es que si seleccionan un azul oscuro y tenemos letras negras, el contraste no es suficiente y no puedes leerlo.Invertir colores opuestos

He intentado hacer una función para obtener el color opuesto inverso pero no he llegado demasiado lejos.

¿Existe tal función?

+1

Hay al menos dos preguntas aquí para esto. Uno es http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color. Lo sé porque implementé un algoritmo de uno de ellos y funciona bien. – Nemi

Respuesta

0

Puede calcular la diferencia entre cada canal de color (rojo, verde y azul) y obtener la diferencia promedio, luego haga una comparación basada en eso.

1

¿El texto tiene que ser un color derivado del color de fondo? ¿Qué pasa si simplemente alterna entre blanco y negro según la intensidad de r g b? La idea es que el blanco siempre será visible en los valores de r g b por debajo de cierta intensidad y el negro siempre visible en el resto.

que no tienen un algoritmo de trabajo para compartir, pero usted podría intentar algo en la línea de:

int threshold = 50; 
if(r < threshold && g < threshold && b < threshold) { 
    // set your font color to white 
} else { 
    // set your font color to black 
} 

Es probable que tenga que jugar con un poco de umbral para conseguir algo bien parecido. También podría teñir la fuente un poco según el valor de r g b que sea dominante.

13

Uso complementary color:

Algo es simple, restar cada componente de color de 255 a conseguir nuevos componentes de color

Color textColor = Color.rgb(255-Color.red(bgColor), 
         255-Color.green(bgColor), 
         255-Color.blue(bgColor)); 

----- EDIT (complemento Como basada RGB puede no funcionar siempre - ------

Estos dos enlaces son muy útiles y en el tema:

http://www.splitbrain.org/blog/2008-09/18-calculating_color_contrast_with_php

http://24ways.org/2010/calculating-color-contrast

+5

¿No es esto un gran problema cuando el usuario selecciona el color 128/128/128 (o algo realmente cerca). – Anthony

+0

He incluido un enlace de Wikipedia en la respuesta. El complemento basado en RGB es más fácil de entender. El complemento basado en HSV funcionará en este caso. @Shynhriir: Sí. El complemento basado en RGB no funcionará en este rango, tiene toda la razón –

+0

¿Cómo codificaría en Android el color complementario del enlace Wiki? –

2

Lo tengo trabajo, creo :)

Aquí es la función:

public static int OpposeColor(int ColorToInvert) 
{ 
    int RGBMAX = 255; 

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

    Log.i("HSV_H", "Start Color=" + ColorToInvert); 

    Color.RGBToHSV(Color.red(ColorToInvert), RGBMAX - Color.green(ColorToInvert), Color.blue(ColorToInvert), hsv); 

    Log.i("HSV_H", "Hue=" + hsv[0]); 
    Log.i("HSV_H", "Saturation=" + hsv[1]); 
    Log.i("HSV_H", "Value=" + hsv[2]); 

    H = (float) (hsv[0] + 0.5); 

    if (H > 1) H -= 1; 

    Log.i("HSV_H", "Hue2=" + H);   

    Log.i("HSV_H", "Color=" + Color.HSVToColor(hsv)); 

    return Color.HSVToColor(hsv); 


} 
+0

¿Por qué ese "RGBMAX -"? y el tono es un valor entre 0 y 360 y no 0 y 1, creo, postet una versión actualizada debajo de –

17

He encontrado que la mejor solución para mí es convertir los valores RGB en valores YIQ . Como solo estamos interesados ​​en el valor de brillo (representado por Y), hay un único cálculo que debe hacerse: Y = (299*R + 587*G + 114*B)/1000. El código Java para que se vería así:

public static Color getContrastColor(Color color) { 
    double y = (299 * color.getRed() + 587 * color.getGreen() + 114 * color.getBlue())/1000; 
    return y >= 128 ? Color.black : Color.white; 
} 

Se puede ver que simplemente decide usar negro o blanco, en base a la luminosidad del color original. Y el resultado funciona muy bien en mi opinión. Los pesos (299, 587, 114) son proporcionales a la sensibilidad de los ojos (o más bien a la sensibilidad de la retina) al color correspondiente.

+1

Gracias. Esto puede no cubrir todos los casos, pero es perfecto para mi caso de uso (hacer que el texto sea legible en un fondo de color) –

+0

Siempre puede leer el texto bastante bien. La desventaja es que el texto será negro o blanco, la información de color del fondo se "perderá". – brimborium

6

basado en la solución marcas que sugeriría:

public static int getComplementaryColor(int colorToInvert) { 
    float[] hsv = new float[3]; 
    Color.RGBToHSV(Color.red(colorToInvert), Color.green(colorToInvert), 
      Color.blue(colorToInvert), hsv); 
    hsv[0] = (hsv[0] + 180) % 360; 
    return Color.HSVToColor(hsv); 
} 

Y, además, ahora creado un método similar, para el cálculo de un fondo por defecto para un color dado: solución

public static int getContrastVersionForColor(int color) { 
    float[] hsv = new float[3]; 
    Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color), 
      hsv); 
    if (hsv[2] < 0.5) { 
     hsv[2] = 0.7f; 
    } else { 
     hsv[2] = 0.3f; 
    } 
    hsv[1] = hsv[1] * 0.2f; 
    return Color.HSVToColor(hsv); 
} 
+0

You 'getComplementaryColor' funciona a la perfección pero no 'getContrastVersionForColor' puede arreglarlo? –

+0

¿Qué quieres decir con que no funciona? No te gusta el resultado? ¿Puedes proporcionar un valor int de color para el que no se ve bien? Lo uso con bastante frecuencia y nunca tuve problemas –

3

entero:

public static int getContrastColor(int color) { 
     double y = (299 * Color.red(color) + 587 * Color.green(color) + 114 * Color.blue(color))/1000; 
     return y >= 128 ? Color.BLACK : Color.WHITE; 
    } 
+1

¿Puede explicarme cómo solucionaría el problema? – Phani

+0

"He intentado hacer una función para obtener el color opuesto inverso pero no he llegado demasiado lejos." Así que aquí hay una función ^^ que devuelve color blanco o negro. – Eboo

+0

Volviendo a la primera pregunta ... si no resuelve el problema ... luego bórrelo ... o actualice la pregunta con los últimos hallazgos. – Phani