¿Cómo puedo determinar la más oscura o más clara la variante de color de un color determinado?

StackOverflow https://stackoverflow.com/questions/97646

  •  01-07-2019
  •  | 
  •  

Pregunta

Dado un color de fuente de cualquier matiz por el sistema o de usuario, me gustaría un algoritmo simple que puede utilizar para trabajar más claro o más oscuro variantes del color seleccionado.Similar a los efectos utilizados en Windows Live Messenger para el estilo de la interfaz de usuario.

El lenguaje es C# con .net 3.5.

Responder a comentario: Formato de Color es (Alfa)RGB.Con valores como el número de bytes o flotadores.

Marca la respuesta: Para el contexto de mi uso (unos simples efectos de interfaz de usuario), la respuesta que yo estoy marcado como aceptado es en realidad la más simple para este contexto.Sin embargo, he dejado de votos a las más complejas y precisas respuestas también.Las personas que hacen más avanzada del color de las operaciones y de encontrar este hilo, en el futuro, definitivamente el registro de aquellos.Muchas gracias.:)

¿Fue útil?

Solución

Simplemente multiplicar los valores RGB de la cantidad que usted desea modificar el nivel.Si uno de los colores que ya está en el valor máximo, entonces usted no puede hacer que sea más brillante (utilizando el VHS de matemáticas de todos modos.)

Esto le da exactamente el mismo resultado, con mucho menos de las matemáticas como cambiar a VHS y, a continuación, modificar V.Esto da el mismo resultado que el cambio a la HSL y, a continuación, la modificación de L, siempre y cuando usted no quiere empezar a perder la saturación.

Otros consejos

En XNA no es el Color.Lerp método estático que hace esto como la diferencia entre los dos colores.

Lerp es una operación matemática entre dos carrozas que cambia el valor de la primera por una proporción de la diferencia entre ellos.

He aquí un método de extensión para hacer a un float:

public static float Lerp( this float start, float end, float amount)
{
    float difference = end - start;
    float adjusted = difference * amount;
    return start + adjusted;
}

Así que, a continuación, un simple lerp operación entre dos colores, el uso de RGB sería:

public static Color Lerp(this Color colour, Color to, float amount)
{
    // start colours as lerp-able floats
    float sr = colour.R, sg = colour.G, sb = colour.B;

    // end colours as lerp-able floats
    float er = to.R, eg = to.G, eb = to.B;

    // lerp the colours to get the difference
    byte r = (byte) sr.Lerp(er, amount),
         g = (byte) sg.Lerp(eg, amount),
         b = (byte) sb.Lerp(eb, amount);

    // return the new colour
    return Color.FromArgb(r, g, b);
}

Un ejemplo de la aplicación de esto sería algo como:

// make red 50% lighter:
Color.Red.Lerp( Color.White, 0.5f );

// make red 75% darker:
Color.Red.Lerp( Color.Black, 0.75f );

// make white 10% bluer:
Color.White.Lerp( Color.Blue, 0.1f );

HSV ( Matiz / Saturación / Valor ), también llamado HSL ( Matiz / Saturación / Luminosidad ) es sólo una diferente representación de color.

El uso de esta representación es que es más fácil para ajustar el brillo.Para convertir de RGB a HSV, iluminar la 'V', a continuación, volver a convertir a RGB.

A continuación se presenta el código C para convertir

void RGBToHSV(unsigned char cr, unsigned char cg, unsigned char cb,double *ph,double *ps,double *pv)
{
double r,g,b;
double max, min, delta;

/* convert RGB to [0,1] */

r = (double)cr/255.0f;
g = (double)cg/255.0f;
b = (double)cb/255.0f;

max = MAXx(r,(MAXx(g,b)));
min = MINx(r,(MINx(g,b)));

pv[0] = max;

/* Calculate saturation */

if (max != 0.0)
    ps[0] = (max-min)/max;
else
    ps[0] = 0.0; 

if (ps[0] == 0.0)
{
    ph[0] = 0.0f;   //UNDEFINED;
    return;
}
/* chromatic case: Saturation is not 0, so determine hue */
delta = max-min;

if (r==max)
{
    ph[0] = (g-b)/delta;
}
else if (g==max)
{
    ph[0] = 2.0 + (b-r)/delta;
}
else if (b==max)
{
    ph[0] = 4.0 + (r-g)/delta;
}
ph[0] = ph[0] * 60.0;
if (ph[0] < 0.0)
    ph[0] += 360.0;
}

void HSVToRGB(double h,double s,double v,unsigned char *pr,unsigned char *pg,unsigned char *pb)
{
int i;
double f, p, q, t;
double r,g,b;

if( s == 0 )
{
    // achromatic (grey)
    r = g = b = v;
}
else
{
    h /= 60;            // sector 0 to 5
    i = (int)floor( h );
    f = h - i;          // factorial part of h
    p = v * ( 1 - s );
    q = v * ( 1 - s * f );
    t = v * ( 1 - s * ( 1 - f ) );
    switch( i )
    {
    case 0:
        r = v;
        g = t;
        b = p;
    break;
    case 1:
        r = q;
        g = v;
        b = p;
    break;
    case 2:
        r = p;
        g = v;
        b = t;
    break;
    case 3:
        r = p;
        g = q;
        b = v;
    break;
    case 4:
        r = t;
        g = p;
        b = v;
    break;
    default:        // case 5:
        r = v;
        g = p;
        b = q;
    break;
    }
}
r*=255;
g*=255;
b*=255;

pr[0]=(unsigned char)r;
pg[0]=(unsigned char)g;
pb[0]=(unsigned char)b;
}

Rica Newman describe de color HSL con respecto a la .Sistema de RED.De dibujo.El Color en su blog e incluso proporciona una HSLColor clase que hace todo el trabajo para usted.Convertir el Sistema.De dibujo.Color a una HSLColor, añadir/restar los valores en contra de la Luminosidad, y convertir de nuevo al Sistema.De dibujo.Color para el uso en su aplicación.

Usted puede convertir su color en el HSL espacio de color, manipular allí y volver a convertir a su espacio de color de su elección (lo más probable es que la RGB)

Los colores más claros tienen un mayor L-valor, más oscura de un menor.

Aquí está el correspondiente a las cosas, y todas las ecuaciones:

http://en.wikipedia.org/wiki/HSL_color_space

Otro método es simplemente interpolar el color con blanco o negro.Esto también desaturar el color un poco, pero es más barato para calcular.

He utilizado el ControlPaint.Oscuro() y .Luz() en el Sistema.Windows.Los formularios.

Supongo que usted está utilizando RGB con los valores de byte (0 a 255) ya que es muy común en todas partes.

Para más brillante, el promedio de los valores RGB con el RGB de color blanco.O, para tener algo de control sobre la cantidad de brillo, mezcla en ellos en una cierta proporción.Vamos f van de 0.0 a 1.0, entonces:

Rnew = (1-f)*R + f*255
Gnew = (1-f)*G + f*255
Bnew = (1-f)*B + f*255

Para más oscuro, utilice el RGB de negro - que, siendo todos los ceros, hace las matemáticas más fácil.

Os dejo los detalles como el resultado de convertir de nuevo en bytes, que probablemente te gustaría hacer.

Si usted está usando los colores RGB quiero transformar este color de parámetros a HSL (matiz, saturación, luminosidad), modificar la ligereza parámetro y, a continuación, transformar de nuevo a RGB.Google a tu alrededor y encontrarás un montón de ejemplos de código sobre cómo hacer estos representación de color transformaciones (RGB para HSL y viceversa).

Esto es lo que encontré rápidamente:http://bytes.com/forum/thread250450.html

Suponiendo que usted obtenga el color RGB, convertir primero a HSV (hue, saturation, value) el espacio de color.A continuación, aumentar/disminuir el valor para producir más claro/más oscuro el tono del color.A continuación, volver a convertir a RGB.

Si sus colores en formato RGB (o, presumiblemente, CMYK), puede utilizar el tosco método de aumento del valor de cada componente de color de la imagen.E. g., en HTML, los colores se representan como tres de dos dígitos de los números hexadecimales.#ff0000 le dará un color rojo brillante, que puede, a continuación, se desvaneció por el aumento de los valores de la G y B componenets por la misma cantidad, como por ejemplo #ff5555 (le da un encendedor rojo).Es de suponer que por el Tono, la Saturación y la Luminosidad (HSL) los colores, usted sólo puede aumentar la componente L, pero no puedo decir con certeza;No estoy tan familiarizado con este espacio de color.

Como digo, sin embargo, este método es bastante crudo.De mis recuerdos de Live Messenger, suena como que usted está tratando de hacer degradados, que se puede aplicar muy fácilmente en Windows Presentation Foundation (WPF, parte de .NET 3.0).WPF es compatible con muchos tipos diferentes de degradado, incluyendo lineal y gradientes radiales.

Puedo recomendar altamente a Adam Nathan libro Windows Presentation Foundation Unleashed como una buena y completa introducción a WPF.

HTH

Cualquier variación en el color que se hace mejor en HSL/VHS.

Es una buena prueba para interpolar entre dos valores equivalentes en el espacio RGB y HSL espacio.La rampa en HSL espacio se ve como una progresión natural.En el espacio RGB que normalmente se ve bastante antinatural.HSL mapas para nuestro visual del espacio de color de percepción mucho mejor que el RGB.

La idea de convertir a VHS o en algún otro espacio de color parece buena, y puede ser necesario para el control preciso del color de trabajo, pero para el común de los efectos de el error de trabajar en RGB puede no ser suficiente para la materia.También, puede ser un dolor para lidiar con el límite de los casos:RGB es un cubo en forma de espacio, mientras que el VHS no es.Si se trabaja con valores de byte, usted puede tener muchos-a-uno y uno-a-muchos mapeos entre los espacios.Esto puede o puede no ser un problema dependiendo de la aplicación.YMMV

Este sitio web las notas que usted puede utilizar el ControlPaint clase dentro de la BCL C# Sistema.Windows.Las formas de espacio de nombres.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top