C #: crea un color más claro / más oscuro basado en un color del sistema

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

  •  03-07-2019
  •  | 
  •  

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?

¿Fue útil?

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:

MSDN: Miembros de 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();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top