C #: crea un color más claro / más oscuro basado en un color del sistema
Pregunta
Duplicar
¿Cómo ajusto el brillo de un color?
¿Cómo puedo determinar más oscuro o ¿Variante de color más claro de un color dado?
Aclarar un color mediante programación
Di que tengo
var c = Color.Red;
Ahora quiero crear un nuevo Color
que sea más claro o más oscuro que ese color. ¿Cómo puedo hacer eso sin demasiados problemas?
Solución
ControlPaint .Light .Dark .DarkDark, etc.
Color lightRed = ControlPaint.Light( Color.Red );
Otros consejos
Recientemente he blogeado sobre esto . La idea principal es aplicar un factor de corrección dado a cada uno de los componentes de color. El siguiente método estático modifica el brillo de un color dado con un factor de corrección específico y produce una variante más oscura o más clara de ese color:
/// <summary>
/// Creates color with corrected brightness.
/// </summary>
/// <param name="color">Color to correct.</param>
/// <param name="correctionFactor">The brightness correction factor. Must be between -1 and 1.
/// Negative values produce darker colors.</param>
/// <returns>
/// Corrected <see cref="Color"/> structure.
/// </returns>
public static Color ChangeColorBrightness(Color color, float correctionFactor)
{
float red = (float)color.R;
float green = (float)color.G;
float blue = (float)color.B;
if (correctionFactor < 0)
{
correctionFactor = 1 + correctionFactor;
red *= correctionFactor;
green *= correctionFactor;
blue *= correctionFactor;
}
else
{
red = (255 - red) * correctionFactor + red;
green = (255 - green) * correctionFactor + green;
blue = (255 - blue) * correctionFactor + blue;
}
return Color.FromArgb(color.A, (int)red, (int)green, (int)blue);
}
También puedes hacer esto usando una función Lerp
. Hay uno en XNA, pero es fácil escribirte.
Consulte mi respuesta a esta pregunta similar para una implementación de C #.
La función te permite hacer esto:
// make red 50% lighter:
Color.Red.Lerp( Color.White, 0.5 );
// make red 75% darker:
Color.Red.Lerp( Color.Black, 0.75 );
// make white 10% bluer:
Color.White.Lerp( Color.Blue, 0.1 );
La mayoría de estos métodos oscurecen el color pero ajustan el tono de manera tal que el resultado no se ve muy bien. La mejor respuesta es usar la clase HSLColor de Rich Newman's y ajustar la luminosidad.
public Color Darken(Color color, double darkenAmount) {
HSLColor hslColor = new HSLColor(color);
hslColor.Luminosity *= darkenAmount; // 0 to 1
return hslColor;
}
Aquí hay un código javascript que uso para aclarar / oscurecer un color determinado. Podría usarlo como base para una función de C # equivalente
Funciona calculando una distancia del blanco puro de cada uno de los componentes RGB y luego ajusta esta distancia según el factor proporcionado. La nueva distancia se utiliza para calcular el nuevo color. Un factor entre 0 y 1 se oscurece, un factor mayor que 1 se aclara
function Darken( hexColor, factor )
{
if ( factor < 0 ) factor = 0;
var c = hexColor;
if ( c.substr(0,1) == "#" )
{
c = c.substring(1);
}
if ( c.length == 3 || c.length == 6 )
{
var i = c.length / 3;
var f; // the relative distance from white
var r = parseInt( c.substr(0, i ), 16 );
f = ( factor * r / (256-r) );
r = Math.floor((256 * f) / (f+1));
r = r.toString(16);
if ( r.length == 1 ) r = "0" + r;
var g = parseInt( c.substr(i, i), 16);
f = ( factor * g / (256-g) );
g = Math.floor((256 * f) / (f+1));
g = g.toString(16);
if ( g.length == 1 ) g = "0" + g;
var b = parseInt( c.substr( 2*i, i),16 );
f = ( factor * b / (256-b) );
b = Math.floor((256 * f) / (f+1));
b = b.toString(16);
if ( b.length == 1 ) b = "0" + b;
c = r+g+b;
}
return "#" + c;
}
Tomando el método central de respuesta de @Pavel , preparé los siguientes dos pequeños métodos de extensión para un uso más intuitivo (al menos para mi) firma.
public static Color LightenBy(this Color color, int percent)
{
return ChangeColorBrightness(color, percent/100.0);
}
public static Color DarkenBy(this Color color, int percent)
{
return ChangeColorBrightness(color, -1 * percent / 100.0);
}
Cambié la función Pavel Vladov para modificar incluso el componente RGB, para obtener matices en cualquier combinación de direcciones R / G / B:
Public Function ChangeColorShades(color As Color, correctionFactor As Single, bR As Boolean, bG As Boolean, bB As Boolean) As Color
Dim red As Single = CSng(color.R)
Dim green As Single = CSng(color.G)
Dim blue As Single = CSng(color.B)
If (correctionFactor < 0) Then
correctionFactor = 1 + correctionFactor
If bR Then
red *= correctionFactor
End If
If bG Then
green *= correctionFactor
End If
If bB Then
blue *= correctionFactor
End If
Else
If bR Then
red = (255 - red) * correctionFactor + red
End If
If bG Then
green = (255 - green) * correctionFactor + green
End If
If bB Then
blue = (255 - blue) * correctionFactor + blue
End If
End If
Return color.FromArgb(color.A, CInt(red), CInt(green), CInt(blue))
End Function
También puedes simplemente trabajar en el porcentaje de RGB para hacerlo más claro o más oscuro como quieras. Aquí tienes un ejemplo de cómo hacer que un color sea más oscuro x% de lo que es:
//_correctionfactory in percentage, e.g 50 = make it darker 50%
private Color DarkerColor(Color color, float correctionfactory = 50f)
{
const float hundredpercent = 100f;
return Color.FromArgb((int)(((float)color.R / hundredpercent) * correctionfactory),
(int)(((float)color.G / hundredpercent) * correctionfactory), (int)(((float)color.B / hundredpercent) * correctionfactory));
}
Otra cosa más es que también podemos revertir el proceso para que sea más liviano. Solo obtenemos el resultado de 255 - RGB y luego lo multiplicamos por el porcentaje que queremos, como el siguiente ejemplo:
private Color LighterColor(Color color, float correctionfactory = 50f)
{
correctionfactory = correctionfactory / 100f;
const float rgb255 = 255f;
return Color.FromArgb((int)((float)color.R + ((rgb255 - (float)color.R) * correctionfactory)), (int)((float)color.G + ((rgb255 - (float)color.G) * correctionfactory)), (int)((float)color.B + ((rgb255 - (float)color.B) * correctionfactory))
);
}
Espero que ayude.
Uso de la biblioteca del convertidor de HSI (búsqueda en google). Y luego, ajuste el canal I para un color más claro / más oscuro.
Echa un vistazo a la clase ControlPaint:
Hice un sitio que hace esto colorglower.com Puede verlo para ver una demostración.
Aquí está el código javascript que utilicé.
function lighten(color) {
// convert to decimal and change luminosity
var luminosity = 0.01
var computedColors = new Array();
var newColor = "#",
c, i, n, black = 0,
white = 255;
for (n = 0; n < 10; n++) {
for (i = 0; i < 3; i++) {
c = parseInt(color.substr(i * 2, 2), 16);
c = Math.round(Math.min(Math.max(black, c + (luminosity * white)), white)).toString(16);
newColor += ("00" + c).substr(c.length);
}
computedColors[n] = newColor;
var arrayUnique = checkIfArrayIsUnique(computedColors);
if (arrayUnique == false) {
computedColors.pop();
break;
}
computedColors[n] = newColor;
newColor = "#";
luminosity += calcPercentage();
}
return computedColors;
}
Lo que hace este código es que recibe un color hexadecimal y luego genera las 10 versiones de color más claro y lo coloca en la matriz. Puede cambiar la luminosidad a lo que desee para ajustar el porcentaje de sombra. Para oscurecer los colores solo necesitas cambiarlos:
luminosity -= calcPercentage();