Comment déterminer une variante de couleur plus foncée ou plus claire d'une couleur donnée?

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

  •  01-07-2019
  •  | 
  •  

Question

Étant donné la couleur source de n'importe quelle teinte du système ou de l'utilisateur, j'aimerais un algorithme simple que je puisse utiliser pour élaborer des variantes plus claires ou plus sombres de la couleur sélectionnée. Identique aux effets utilisés sur Windows Live Messenger pour le style de l'interface utilisateur.

La langue est C # avec .net 3.5.

En réponse au commentaire: le format de couleur est (Alpha) RGB. Avec des valeurs en octets ou en flotteurs.

Réponse de marquage: Pour le contexte de mon utilisation (quelques effets d'interface utilisateur simples), la réponse que je marque comme acceptée est en réalité la plus simple pour ce contexte. Cependant, j'ai abandonné les votes pour les réponses plus complexes et précises. Toute personne effectuant des opérations de couleur plus avancées et recherchant ce fil à l'avenir doit absolument les vérifier. Merci beaucoup. :)

Était-ce utile?

La solution

Il suffit de multiplier les valeurs RVB par le montant que vous souhaitez modifier le niveau. Si l’une des couleurs est déjà à la valeur maximale, vous ne pouvez pas la rendre plus lumineuse (en utilisant de toute façon les calculs HSV.)

Cela donne exactement le même résultat avec beaucoup moins de maths que de passer à HSV puis de modifier V. Cela donne le même résultat que de basculer vers HSL puis de modifier L, tant que vous ne voulez pas perdre la saturation.

Autres conseils

Dans XNA, il y a le < code> Color.Lerp une méthode statique qui crée la différence entre deux couleurs.

Lerp est une opération mathématique entre deux flottants qui modifie la valeur du premier par un rapport de la différence entre eux.

Voici une méthode d'extension pour le faire sur un float :

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

Dans ce cas, une opération lerp simple entre deux couleurs utilisant RVB serait:

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);
}

Voici un exemple d'application:

// 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 (Teinte / Saturation / Valeur) également appelé HSL (Teinte / Saturation / Luminosité) est simplement une représentation de couleur différente.

L’utilisation de cette représentation facilite le réglage de la luminosité. Convertissez donc RVB en HSV, illuminez le "V", puis reconvertissez-le en RVB.

Ci-dessous, quelques codes C à 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;
}
Rich Newman 2 / "rel =" noreferrer "> discute de la couleur HSL en ce qui concerne .NET System.Drawing.Color sur son blog et même fournit une classe HSLColor qui effectue tout le travail à votre place. Convertissez votre System.Drawing.Color en HSLColor, ajoutez / soustrayez des valeurs à la luminosité et reconvertissez-le en System.Drawing.Color pour l’utiliser dans votre application.

Vous pouvez convertir votre couleur dans l'espace colorimétrique HSL, la manipuler là-bas et la reconvertir dans l'espace colorimétrique de votre choix (il s'agit probablement de RVB)

Les couleurs plus claires ont une valeur L plus élevée, plus foncées une plus faible.

Voici le matériel pertinent et toutes les équations:

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

Une autre méthode consiste à interpoler votre couleur avec du blanc ou du noir. Cela désaturera également un peu la couleur, mais son calcul est moins coûteux.

J'ai utilisé ControlPaint.Dark () et .Light () dans System.Windows.Forms.

Je suppose que vous utilisez RVB avec des valeurs d'octet (0 à 255), ce qui est très courant partout.

Pour plus de luminosité, faites la moyenne des valeurs RVB avec le RVB de blanc. Ou, pour avoir un certain contrôle sur la quantité d'éclaircissement, mélangez-les dans une certaine proportion. Laissez f varier de 0.0 à 1.0, puis:

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

Pour les couleurs plus sombres, utilisez le RVB noir - ce qui facilite les calculs, étant tous des zéros.

Je laisse de côté certains détails, tels que la reconversion du résultat en octets, ce que vous voudrez probablement faire.

Si vous utilisez des couleurs RVB, je transformerais ces paramètres de couleur en HSL (teinte, saturation, luminosité), modifiez le paramètre luminosité, puis revenez en RVB. Dans les environs de Google, vous trouverez de nombreux exemples de code expliquant comment effectuer ces transformations de représentation des couleurs (RVB en HSL et vice-versa).

Voici ce que j'ai rapidement trouvé: http://bytes.com/forum/thread250450.html

En supposant que la couleur soit RVB, convertissez-la d'abord en espace colorimétrique HSV (teinte, saturation, valeur). Puis augmentez / diminuez la valeur pour produire une nuance plus claire / plus sombre de la couleur. Puis reconvertissez en RVB.

Si vos couleurs sont au format RVB (ou vraisemblablement en CMJN), vous pouvez utiliser la méthode assez grossière consistant à augmenter la valeur de chaque composant de la couleur. Par exemple, en HTML, les couleurs sont représentées par trois nombres hexadécimaux à deux chiffres. # ff0000 vous donnera un rouge vif, qui peut ensuite être atténué en augmentant les valeurs des composants G et B de la même quantité, comme # ff5555 (donne un rouge plus clair). Vraisemblablement pour les couleurs Hue, Saturation and Lightness (HSL), vous pouvez simplement augmenter la composante L, mais je ne peux pas le dire avec certitude; Je connais moins bien cet espace couleur.

Comme je le disais cependant, cette méthode est assez rudimentaire. D'après mes souvenirs de Live Messenger, il semblerait que vous essayiez de créer des dégradés, qui peuvent être appliqués très facilement dans Windows Presentation Foundation (WPF, composant de .NET 3.0). WPF prend en charge de nombreux types de styles de dégradé, notamment les dégradés linéaires et radiaux.

Je recommande vivement le livre d'Adam Nathan Windows Presentation Foundation Unleashed constitue une bonne et complète introduction à WPF.

HTH

Toutes les variations de couleur sont mieux réalisées en HSL / HSV.

Un bon test consiste à interpoler entre deux valeurs équivalentes dans l’espace RVB et dans l’espace TSL. La rampe dans l'espace HSL ressemble à une progression naturelle. Dans les espaces RVB, cela ne semble généralement pas naturel. HSL correspond bien mieux à notre perception visuelle de l'espace colorimétrique que RVB.

L'idée de convertir au HSV ou à un autre espace colorimétrique semble bonne et peut être nécessaire pour un travail de couleur précis, mais pour des besoins ordinaires, l'erreur de travailler en RVB peut ne pas suffire. En outre, il peut être difficile de traiter les cas limites: le RVB est un espace en forme de cube, contrairement au HSV. Si vous travaillez avec des valeurs d'octet, vous pouvez avoir des mappages plusieurs à un et un à plusieurs entre les espaces. Cela peut être ou ne pas être un problème en fonction de l'application. YMMV

Ce site Web indique que vous pouvez utiliser le Classe ControlPaint dans l'espace de noms BCL C # System.Windows.Forms.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top