remarks generate example c# colors

generate - params comments c#



¿Cómo determino la variante de color más oscura o más clara de un color dado? (13)

Dado un color de fuente de cualquier matiz por el sistema o el usuario, me gustaría un algoritmo simple que pueda usar para encontrar variantes más claras o más oscuras del color seleccionado. Similar a los efectos utilizados en Windows Live Messenger para diseñar la interfaz de usuario.

El lenguaje es C # con .net 3.5.

Respondiendo para comentar: el formato de color es (Alpha) RGB. Con valores como bytes o flotantes.

Marcado de respuesta: para el contexto de mi uso (algunos efectos simples de IU), la respuesta que estoy marcando como aceptada es la más simple para este contexto. Sin embargo, también he renunciado a las respuestas más complejas y precisas. Cualquiera que realice operaciones de color más avanzadas y encuentre este hilo en el futuro definitivamente debería verificarlas. Gracias. :)


Cualquier variación en el color se realiza mejor en HSL / HSV.

Una buena prueba es interpolar entre dos valores equivalentes en el espacio RGB y el espacio HSL. La rampa en el espacio HSL parece una progresión natural. En el espacio RGB, por lo general, parece bastante antinatural. HSL asigna a nuestra percepción del espacio de color visual mucho mejor que RGB.


Este sitio web señala que puede usar la clase ControlPaint dentro del espacio de nombres BCL C # System.Windows.Forms.


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

Usando esta representación es más fácil ajustar el brillo. Así que convierte de RGB a HSV, ilumina la ''V'', luego vuelve a convertir a RGB.

A continuación se muestra un 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; }


He usado ControlPaint.Dark () y .Light () en System.Windows.Forms.


La idea de convertir a HSV u otro espacio de color parece buena, y puede ser necesaria para un trabajo de color preciso, pero para fines ordinarios, el error de trabajar en RGB puede no ser suficiente. Además, puede ser una molestia lidiar con casos límite: RGB es un espacio en forma de cubo, mientras que HSV no lo es. Si trabaja con valores de bytes, puede tener asignaciones de muchos a uno y uno a muchos entre los espacios. Esto puede o no ser un problema dependiendo de la aplicación. YMMV


Puede convertir su color en el espacio de color HSL, manipularlo allí y convertir de nuevo a su espacio de color de preferencia (lo más probable es que sea RGB)

Los colores más claros tienen un valor L más alto, más oscuro y más bajo.

Aquí están las cosas relevantes y todas las ecuaciones:

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

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


Rich Newman analiza el color HSL con respecto a .NET System.Drawing.Color en su blog e incluso proporciona una clase HSLColor que hace todo el trabajo por usted. Convierta su System.Drawing.Color en un HSLColor, agregue / reste valores contra la luminosidad, y conviértalo nuevamente a System.Drawing.Color para usar en su aplicación.


Si está usando colores RGB, transformaría estos parámetros de color a HSL (matiz, saturación, luminosidad), modificaré el parámetro de luminosidad y luego lo volveré a transformar en RGB. Busque en Google y encontrará una gran cantidad de muestras de código sobre cómo hacer estas transformaciones de representación de color (RGB a HSL y viceversa).

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


Si sus colores están en formato RGB (o, presumiblemente, CMYK), puede utilizar el método bastante crudo para aumentar el valor de cada componente del color. Por ejemplo, en HTML los colores se representan como tres números hexadecimales de dos dígitos. # ff0000 le dará un rojo brillante, que luego se puede atenuar aumentando los valores de los componentes G y B en la misma cantidad, como # ff5555 (da un rojo más claro). Presumiblemente para los colores Hue, Saturation y Lightness (HSL), puedes simplemente elevar el componente L, pero no puedo decirlo con certeza; Estoy menos familiarizado con este espacio de color.

Como digo, sin embargo, este método es bastante crudo. De mis recuerdos de Live Messenger, parece que estás tratando de hacer degradados, que se pueden aplicar muy fácilmente en Windows Presentation Foundation (WPF, parte de .NET 3.0). WPF admite muchos tipos diferentes de pincel de degradado, incluidos degradados lineales y radiales.

Recomiendo encarecidamente el libro de Adam Nathan, Windows Presentation Foundation Unleashed, como una introducción buena y completa a WPF.

HTH


Simplemente multiplique los valores RGB por la cantidad por la que desea modificar el nivel. Si uno de los colores ya está en el valor máximo, entonces no se puede hacer más brillante (usando las matemáticas HSV de todos modos).

Esto da exactamente el mismo resultado con mucha menos matemática que cambiar a HSV y luego modificar V. Esto da el mismo resultado que cambiar a HSL y luego modificar L, siempre y cuando no quieras comenzar a perder saturación.


Supongo que estás usando RGB con valores de bytes (0 a 255) ya que es muy común en todas partes.

Para obtener más brillo, promedie los valores RGB con el RGB de blanco. O bien, para tener cierto control sobre la cantidad de brillo, mezcle en ellos en cierta proporción. Deje f variar de 0.0 a 1.0, luego:

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, al ser todos ceros, facilita las matemáticas.

Olvidé detalles como convertir el resultado en bytes, lo que probablemente querría hacer.


Suponiendo que obtiene el color como RGB, primero conviértalo en un espacio de color HSV (tono, saturación, valor). A continuación, aumente / disminuya el valor para producir un tono más claro / más oscuro del color. Luego vuelve a convertir a RGB.


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

Lerp es una operación matemática entre dos flotadores que cambia el valor del primero por una relación de la diferencia entre ellos.

Aquí hay un método de extensión para hacerlo en un float :

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

Entonces, una simple operación de lerp entre dos colores usando 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 aplicación de esto sería algo así 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 );