Dado um valor RGB, como crio uma tonalidade (ou sombra)?

124

Dado um valor RGB, por exemplo 168, 0, 255, como faço para criar tonalidades (torná-lo mais claro) e tons (torná-lo mais escuro) da cor?

DenaliHardtail
fonte

Respostas:

153

Entre várias opções para sombreamento e tonalidade:

  • Para tons, multiplique cada componente por 1/4, 1/2, 3/4 etc. do valor anterior. Quanto menor o fator, mais escura a sombra.

  • Para matizes, calcule (255 - valor anterior), multiplique por 1/4, 1/2, 3/4, etc. (quanto maior o fator, mais clara a matiz) e adicione-a ao valor anterior (assumindo que cada .component é um número inteiro de 8 bits).

Observe que as manipulações de cores (como tonalidades e outros sombreados) devem ser feitas em RGB linear . No entanto, é provável que as cores RGB especificadas em documentos ou codificadas em imagens e vídeos sejam RGB linear; nesse caso, a chamada função de transferência inversa precisa ser aplicada a cada um dos componentes da cor RGB. Esta função varia de acordo com o espaço de cores RGB. Por exemplo, no espaço de cores sRGB (que pode ser assumido se o espaço de cores RGB for desconhecido), essa função é aproximadamente equivalente a aumentar cada componente de cor sRGB (variando de 0 a 1) para uma potência de 2,2. (Observe que "RGB linear" não é um espaço de cores RGB.)

Veja também o comentário de Violet Giraffe sobre "correção gama".

Peter O.
fonte
20
Eu tentei isso e funcionou muito bem. Eu pensei que seria útil escrever exemplos das fórmulas. Original (r, g, b); Sombra (rs, GS, sl): rs = r * 0.25, gs = g * 0.25, bs = b * 0.25(que é uma máscara muito escura); Matiz (ta, GT, bt): rt = r + (0.25 * (255 - r)), gt = g + (0.25 * (255 - g)), bt = b + (0.25 * (255 - b))(que é um tom muito claro). Eu fiz isso como parte de uma matriz legal que criou muitos tons e funcionou muito bem. Espero que ajude. Obrigado Peter.
Thomas
1
Você cometeu um erro. É viceversa.
Francesco Menzani
Você tem certeza de que essa manipulação não deve ser responsável pela correção de gama?
Violet Giraffe
1
@VioletGiraffe: Você faz um bom argumento com correção de gama. Veja minha edição. (Isso substitui um comentário excluído meu de 22 horas atrás).
Peter O.
97

Algumas definições

  • Uma sombra é produzida "escurecendo" uma tonalidade ou "adicionando preto"
  • Uma tonalidade é produzida "ligthening" uma tonalidade ou "adicionando branco"

Criando uma tonalidade ou sombra

Dependendo do modelo de cores, existem métodos diferentes para criar uma cor mais escura (sombreada) ou mais clara (matizada):

  • RGB:

    • Sombrear:

      newR = currentR * (1 - shade_factor)
      newG = currentG * (1 - shade_factor)
      newB = currentB * (1 - shade_factor)
      
    • Para tingir:

      newR = currentR + (255 - currentR) * tint_factor
      newG = currentG + (255 - currentG) * tint_factor
      newB = currentB + (255 - currentB) * tint_factor
      
    • De maneira mais geral, a cor que resulta em camadas de RGB(currentR,currentG,currentB)uma cor RGBA(aR,aG,aB,alpha)é:

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

    onde (aR,aG,aB) = black = (0,0,0)para sombreamento e (aR,aG,aB) = white = (255,255,255)tingimento

  • HSVou HSB:

    • Para sombrear: abaixe Value/ Brightnessou aumente oSaturation
    • Para matizar: abaixe Saturationou aumente Value/Brightness
  • HSL:
    • Para sombrear: abaixe o Lightness
    • Para matizar: aumente o Lightness

Existem fórmulas para converter de um modelo de cores para outro. De acordo com sua pergunta inicial, se você está dentro RGBe deseja usar o HSVmodelo para sombrear, por exemplo, basta converter para HSV, fazer o sombreamento e converter novamente para RGB. A fórmula para converter não é trivial, mas pode ser encontrada na internet. Dependendo do seu idioma, ele também pode estar disponível como uma função principal:

Comparando os modelos

  • RGB tem a vantagem de ser realmente simples de implementar, mas:
    • você só pode sombrear ou tingir sua cor relativamente
    • você não tem idéia se sua cor já está colorida ou sombreada
  • HSVou HSBé meio complexo porque você precisa jogar com dois parâmetros para obter o que deseja ( Saturation& Value/ Brightness)
  • HSL é o melhor do meu ponto de vista:
    • suportado por CSS3 (para webapp)
    • simples e preciso:
      • 50% significa um Hue inalterado
      • >50% significa que o matiz é mais claro (matiz)
      • <50% significa que o matiz é mais escuro (sombra)
    • dada uma cor, você pode determinar se ela já está colorida ou sombreada
    • você pode colorir ou sombrear uma cor de forma relativamente ou absoluta (apenas substituindo a Lightnesspeça)

JBE
fonte
1
Eu acredito aqui: "Uma sombra é produzida pelo" escurecimento "de uma tonalidade" ; por tonalidade, você quer dizer a cor. Porque se você está falando sobre matiz como no HSL / HSV, alterá-lo produzirá uma cor diferente, não um tom / tonalidade. A matiz (0-360 °), por si só, não pode ficar mais escura / mais clara. Para dar um tom de cor / matiz, seria necessário modificar os valores de SL / SV. Essa definição pode induzir alguém a pensar que mudar a tonalidade produzirá uma cor mais escura / mais clara.
akinuri
A versão sombreada funciona apenas para o intervalo de cores a partir de 0. Adicione metade do seu intervalo de cores ao valor do canal de cores, faça as contas e subtraia esse intervalo novamente. Se sua cor estiver assinada e você puder fazer o cálculo sem destruir algo por causa do estouro, isso funcionará conforme o esperado.
T0b4cc0
3

Atualmente, estou experimentando telas e pixels ... Estou descobrindo que essa lógica funciona melhor para mim.

  1. Use isso para calcular o acinzentado (luma?)
  2. mas com o valor existente e o novo valor 'tonalidade'
  3. calcular a diferença (descobri que não precisava multiplicar)
  4. adicione para compensar o valor 'tonalidade'

    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 algo assim...

Blair
fonte