Étant donné une valeur RVB, comment créer une teinte (ou une nuance)?

124

Étant donné une valeur RVB, comme 168, 0, 255, comment créer des teintes (la rendre plus claire) et des nuances (la rendre plus foncée) de la couleur?

DenaliHardtail
la source

Réponses:

153

Parmi plusieurs options d'ombrage et de teinture:

  • Pour les nuances, multipliez chaque composant par 1/4, 1/2, 3/4, etc., de sa valeur précédente. Plus le facteur est petit, plus la teinte est foncée.

  • Pour les teintes, calculez (255 - valeur précédente), multipliez cela par 1/4, 1/2, 3/4, etc. (plus le facteur est élevé, plus la teinte est claire), et ajoutez cela à la valeur précédente (en supposant que chaque .component est un entier de 8 bits).

Notez que les manipulations de couleur (telles que les teintes et autres ombres) doivent être effectuées en RVB linéaire . Cependant, les couleurs RVB spécifiées dans les documents ou encodées dans les images et la vidéo ne sont pas susceptibles d'être en RVB linéaire, auquel cas une fonction dite de transfert inverse doit être appliquée à chacun des composants de la couleur RVB. Cette fonction varie avec l'espace colorimétrique RVB. Par exemple, dans l'espace colorimétrique sRGB (qui peut être supposé si l'espace colorimétrique RVB est inconnu), cette fonction équivaut à peu près à élever chaque composante de couleur sRGB (allant de 0 à 1) à une puissance de 2,2. (Notez que "RVB linéaire" n'est pas un espace colorimétrique RVB.)

Voir aussi le commentaire de Violet Giraffe sur la "correction gamma".

Peter O.
la source
20
J'ai essayé cela et cela a très bien fonctionné. J'ai pensé qu'il serait utile d'écrire des exemples de formules. Original (r, g, b); Shade (rs, gs, bs): rs = r * 0.25, gs = g * 0.25, bs = b * 0.25(qui est une jolie teinte foncée); Teinte (rt, gt, bt): rt = r + (0.25 * (255 - r)), gt = g + (0.25 * (255 - g)), bt = b + (0.25 * (255 - b))(qui est une teinte assez léger). Je l'ai fait dans le cadre d'un tableau cool qui a créé beaucoup de teintes et cela a très bien fonctionné. J'espère que cela pourra aider. Merci Peter.
Thomas
1
Vous avez fait une erreur. C'est l'inverse.
Francesco Menzani
Etes-vous sûr que ces manipulations ne doivent pas tenir compte de la correction gamma?
Violet Giraffe
1
@VioletGiraffe: Vous faites un bon point avec la correction gamma. Voir ma modification. (Cela remplace un de mes commentaires supprimés d'il y a 22 heures.)
Peter O.26
97

Quelques définitions

  • Une nuance est produite en "assombrissant" une teinte ou en "ajoutant du noir"
  • Une teinte est produite en "éclaircissant" une teinte ou en "ajoutant du blanc"

Créer une teinte ou une nuance

En fonction de votre modèle de couleur, il existe différentes méthodes pour créer une couleur plus foncée (ombrée) ou plus claire (teintée):

  • RGB:

    • Pour ombrager:

      newR = currentR * (1 - shade_factor)
      newG = currentG * (1 - shade_factor)
      newB = currentB * (1 - shade_factor)
      
    • Pour teinter:

      newR = currentR + (255 - currentR) * tint_factor
      newG = currentG + (255 - currentG) * tint_factor
      newB = currentB + (255 - currentB) * tint_factor
      
    • Plus généralement, la couleur résultant de la superposition d'une couleur RGB(currentR,currentG,currentB)avec une couleur RGBA(aR,aG,aB,alpha)est:

      newR = currentR + (aR - currentR) * alpha
      newG = currentG + (aG - currentG) * alpha
      newB = currentB + (aB - currentB) * alpha
      

    (aR,aG,aB) = black = (0,0,0)pour l'ombrage et (aR,aG,aB) = white = (255,255,255)pour la teinture

  • HSVou HSB:

    • Pour ombrer: baisser le Value/ Brightnessou augmenter leSaturation
    • Pour teinter: abaissez Saturationou augmentez le Value/Brightness
  • HSL:
    • Pour ombrager: abaissez le Lightness
    • Pour teinter: augmentez la Lightness

Il existe des formules pour convertir d'un modèle de couleur à un autre. Selon votre question initiale, si vous êtes RGBet souhaitez utiliser le HSVmodèle pour ombrer par exemple, vous pouvez simplement convertir en HSV, faire l'ombrage et reconvertir en RGB. Les formules à convertir ne sont pas anodines mais peuvent être trouvées sur Internet. Selon votre langue, il peut également être disponible en tant que fonction principale:

Comparaison des modèles

  • RGB a l'avantage d'être très simple à mettre en œuvre, mais:
    • vous ne pouvez nuancer ou teinter votre couleur que relativement
    • vous n'avez aucune idée si votre couleur est déjà teintée ou ombrée
  • HSVou HSBest un peu complexe car vous devez jouer avec deux paramètres pour obtenir ce que vous voulez ( Saturation& Value/ Brightness)
  • HSL est le meilleur de mon point de vue:
    • pris en charge par CSS3 (pour webapp)
    • simple et précis:
      • 50% signifie une teinte inchangée
      • >50% signifie que la teinte est plus claire (teinte)
      • <50% signifie que la teinte est plus sombre (ombre)
    • étant donné une couleur, vous pouvez déterminer si elle est déjà teintée ou ombrée
    • vous pouvez teinter ou nuancer une couleur relativement ou absolument (en remplaçant simplement la Lightnesspièce)

JBE
la source
1
Je crois ici "Une nuance est produite en" assombrissant "une teinte" , par teinte, vous entendez la couleur. Parce que si vous parlez de teinte comme dans HSL / HSV, la changer produira une couleur différente, pas une nuance / une teinte. La teinte (0-360 °), à elle seule, ne peut pas devenir plus sombre / plus claire. Pour donner une nuance / une teinte de couleur, il faudrait modifier les valeurs SL / SV. Cette définition pourrait induire quelqu'un en erreur en pensant que changer la teinte produira une couleur plus foncée / plus claire.
akinuri
La version de nuance ne fonctionne que pour la gamme de couleurs à partir de 0. Ajoutez la moitié de votre gamme de couleurs à la valeur du canal de couleur, puis faites le calcul puis soustrayez à nouveau cette gamme. Si votre couleur est signée et que vous pouvez faire le calcul sans détruire quelque chose à cause d'un débordement, cela fonctionne comme prévu.
t0b4cc0
3

J'expérimente actuellement avec des toiles et des pixels ... Je trouve que cette logique fonctionne mieux pour moi.

  1. Utilisez ceci pour calculer la grisaille (luma?)
  2. mais avec à la fois la valeur existante et la nouvelle valeur de 'teinte'
  3. calculer la différence (j'ai trouvé que je n'avais pas besoin de multiplier)
  4. ajouter pour compenser la valeur de 'teinte'

    var grey =  (r + g + b) / 3;    
    var grey2 = (new_r + new_g + new_b) / 3;
    
    var dr =  grey - grey2 * 1;    
    var dg =  grey - grey2 * 1    
    var db =  grey - grey2 * 1;  
    
    tint_r = new_r + dr;    
    tint_g = new_g + dg;   
    tint_b = new_b _ db;
    

ou quelque chose comme ça...

Blair
la source