Dato un valore RGB, come creo una tinta (o sfumatura)?


124

Dato un valore RGB, come 168, 0, 255, come faccio a creare tinte (renderlo più chiaro) e sfumature (renderlo più scuro) del colore?

Risposte:


153

Tra le diverse opzioni per l'ombreggiatura e la colorazione:

  • Per le sfumature, moltiplicare ogni componente per 1/4, 1/2, 3/4, ecc. Del suo valore precedente. Più piccolo è il fattore, più scura è l'ombra.

  • Per le tinte, calcolare (255 - valore precedente), moltiplicarlo per 1/4, 1/2, 3/4, ecc. (Maggiore è il fattore, più chiara è la tinta) e aggiungerlo al valore precedente (assumendo che .component è un numero intero a 8 bit).

Notare che le manipolazioni del colore (come tinte e altre ombreggiature) dovrebbero essere eseguite in RGB lineare . Tuttavia, è improbabile che i colori RGB specificati nei documenti o codificati in immagini e video siano in RGB lineare, nel qual caso è necessario applicare una cosiddetta funzione di trasferimento inverso a ciascuno dei componenti del colore RGB. Questa funzione varia con lo spazio colore RGB. Ad esempio, nello spazio colore sRGB (che può essere assunto se lo spazio colore RGB è sconosciuto), questa funzione è più o meno equivalente all'aumento di ogni componente colore sRGB (compreso tra 0 e 1) a una potenza di 2,2. (Notare che "RGB lineare" non è uno spazio colore RGB.)

Vedi anche il commento di Violet Giraffe sulla "correzione gamma".


20
L'ho provato e ha funzionato benissimo. Ho pensato che sarebbe stato utile scrivere esempi delle formule. Originale (r, g, b); Shade (rs, GS, BS): rs = r * 0.25, gs = g * 0.25, bs = b * 0.25(vale a dire una tonalità scura abbastanza); Tint (rt, gt, bt): rt = r + (0.25 * (255 - r)), gt = g + (0.25 * (255 - g)), bt = b + (0.25 * (255 - b))(che è una tinta abbastanza luce). L'ho fatto come parte di una fantastica gamma che ha creato molte tonalità e ha funzionato alla grande. Spero che aiuti. Grazie Peter.
Thomas,

1
Hai fatto un errore. È viceversa.
Francesco Menzani

Sei sicuro che queste manipolazioni non debbano tenere conto della correzione gamma?
Violet Giraffe

1
@VioletGiraffe: sei un buon punto con la correzione gamma. Vedi la mia modifica. (Questo sostituisce un mio commento cancellato di 22 ore fa.)
Peter O.

97

Alcune definizioni

  • Una tonalità viene prodotta "scurendo" una tonalità o "aggiungendo nero"
  • Una tinta viene prodotta "illuminando" una tonalità o "aggiungendo bianco"

Creare una tinta o un'ombra

A seconda del modello di colore, esistono diversi metodi per creare un colore più scuro (sfumato) o più chiaro (colorato):

  • RGB:

    • Per ombreggiare:

      newR = currentR * (1 - shade_factor)
      newG = currentG * (1 - shade_factor)
      newB = currentB * (1 - shade_factor)
      
    • Per colorare:

      newR = currentR + (255 - currentR) * tint_factor
      newG = currentG + (255 - currentG) * tint_factor
      newB = currentB + (255 - currentB) * tint_factor
      
    • Più in generale, il colore risultante nella stratificazione di un colore RGB(currentR,currentG,currentB)con un colore RGBA(aR,aG,aB,alpha)è:

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

    dove (aR,aG,aB) = black = (0,0,0)per l'ombreggiatura e (aR,aG,aB) = white = (255,255,255)per la colorazione

  • HSVoppure HSB:

    • Per ombreggiare: abbassare il Value/ Brightnesso aumentare ilSaturation
    • Per colorare: abbassare Saturationo aumentare il Value/Brightness
  • HSL:
    • Per ombreggiare: abbassare il Lightness
    • Per colorare: aumentare il Lightness

Esistono formule per convertire da un modello di colore a un altro. Secondo la tua domanda iniziale, se ti trovi RGBe desideri utilizzare il HSVmodello per ombreggiare, ad esempio, puoi semplicemente convertirlo in HSV, eseguire l'ombreggiatura e riconvertirlo in RGB. Le formule per convertire non sono banali ma si possono trovare su internet. A seconda della tua lingua, potrebbe anche essere disponibile come funzione principale:

Confrontando i modelli

  • RGB ha il vantaggio di essere davvero semplice da implementare, ma:
    • puoi solo sfumare o colorare il tuo colore relativamente
    • non hai idea se il tuo colore è già colorato o sfumato
  • HSVo HSBè un po 'complesso perché devi giocare con due parametri per ottenere quello che vuoi ( Saturation& Value/ Brightness)
  • HSL è il migliore dal mio punto di vista:
    • supportato da CSS3 (per webapp)
    • semplice e preciso:
      • 50% indica una tonalità inalterata
      • >50% significa che la tonalità è più chiara (tinta)
      • <50% significa che la tonalità è più scura (ombra)
    • dato un colore è possibile determinare se è già colorato o sfumato
    • puoi colorare o sfumare un colore in modo relativo o assoluto (semplicemente sostituendo la Lightnessparte)


1
Io credo qui "Una tonalità è prodotta" scurendo "una tonalità" , per tonalità, intendi il colore. Perché se stai parlando di tonalità come in HSL / HSV, cambiandola produrrà un colore diverso, non una tonalità / tinta. La tonalità (0-360 °), da sola, non può diventare più scura / chiara. Per dare una sfumatura / tinta di colore, si dovrebbero modificare i valori SL / SV. Questa definizione potrebbe indurre qualcuno a pensare che cambiare la tonalità produrrà un colore più scuro / più chiaro.
akinuri

La versione ombra funziona solo per la gamma di colori a partire da 0. Aggiungi metà della tua gamma di colori al valore del canale del colore, quindi esegui i calcoli e sottrai di nuovo quella gamma. Se il tuo colore è firmato e puoi eseguire il calcolo senza distruggere qualcosa a causa dell'overflow, funziona come previsto.
t0b4cc0

3

Attualmente sto sperimentando con canvas e pixel ... Sto scoprendo che questa logica funziona meglio per me.

  1. Usalo per calcolare il grigiore (luminanza?)
  2. ma sia con il valore esistente che con il nuovo valore 'tinta'
  3. calcolare la differenza (ho scoperto che non avevo bisogno di moltiplicare)
  4. aggiungi per compensare il valore 'tinta'

    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;
    

o qualcosa di simile...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.