Biorąc pod uwagę wartość RGB, jak utworzyć odcień (lub odcień)?

124

Biorąc pod uwagę wartość RGB, na przykład 168, 0, 255, w jaki sposób mogę utworzyć odcienie (rozjaśnić) i odcienie (przyciemnić) koloru?

DenaliHardtail
źródło

Odpowiedzi:

153

Wśród kilku opcji cieniowania i barwienia:

  • W przypadku odcieni pomnóż każdy składnik przez 1/4, 1/2, 3/4 itd. Poprzedniej wartości. Im mniejszy współczynnik, tym ciemniejszy odcień.

  • W przypadku odcieni oblicz (255 - poprzednia wartość), pomnóż to przez 1/4, 1/2, 3/4 itd. (Im większy współczynnik, tym jaśniejszy odcień) i dodaj to do poprzedniej wartości (zakładając, że każda .component to 8-bitowa liczba całkowita).

Zwróć uwagę, że manipulacje kolorami (takie jak odcienie i inne cieniowanie) powinny być wykonywane w liniowym RGB . Jednak kolory RGB określone w dokumentach lub zakodowane w obrazach i wideo prawdopodobnie nie będą w liniowym RGB, w takim przypadku tak zwana funkcja odwrotnego transferu musi zostać zastosowana do każdego ze składników koloru RGB. Ta funkcja różni się w zależności od przestrzeni kolorów RGB. Na przykład w przestrzeni kolorów sRGB (co można założyć, jeśli przestrzeń kolorów RGB jest nieznana), ta funkcja jest z grubsza równoważna podniesieniu każdego składnika koloru sRGB (w zakresie od 0 do 1) do potęgi 2,2. (Zwróć uwagę, że „liniowy RGB” nie jest przestrzenią kolorów RGB).

Zobacz także komentarz Violet Giraffe na temat „korekcji gamma”.

Peter O.
źródło
20
Wypróbowałem to i działało świetnie. Pomyślałem, że pomocne będzie napisanie przykładów wzorów. Oryginał (r, g, b); Cień (RS, gs, bs): rs = r * 0.25, gs = g * 0.25, bs = b * 0.25(który jest bardzo ciemny odcień); Tint (RT GT, bt) rt = r + (0.25 * (255 - r)), gt = g + (0.25 * (255 - g)), bt = b + (0.25 * (255 - b))(który jest bardzo lekki odcień). Zrobiłem to jako część fajnej tablicy, która stworzyła wiele odcieni i działała świetnie. Mam nadzieję, że to pomoże. Dzięki Peter.
Thomas,
1
Popełniłeś błąd. To jest odwrotnie.
Francesco Menzani
Czy na pewno te manipulacje nie mogą uwzględniać korekcji gamma?
Violet Giraffe
1
@VioletGiraffe: Masz rację, jeśli chodzi o korekcję gamma. Zobacz moją edycję. (To zastępuje mój usunięty komentarz sprzed 22 godzin.)
Peter O.
97

Kilka definicji

  • Odcień wytwarza się „zaciemnienie” odcień lub „dodaniu czerni”
  • Odcień wytwarza się „ligthening” odcień lub „dodając znak”

Tworzenie odcienia lub cienia

W zależności od modelu kolorów istnieją różne metody tworzenia ciemniejszego (cieniowanego) lub jaśniejszego (podbarwionego) koloru:

  • RGB:

    • Zacienić:

      newR = currentR * (1 - shade_factor)
      newG = currentG * (1 - shade_factor)
      newB = currentB * (1 - shade_factor)
      
    • Aby zabarwić:

      newR = currentR + (255 - currentR) * tint_factor
      newG = currentG + (255 - currentG) * tint_factor
      newB = currentB + (255 - currentB) * tint_factor
      
    • Bardziej ogólnie, kolor powodujący nałożenie koloru RGB(currentR,currentG,currentB)na kolor RGBA(aR,aG,aB,alpha)to:

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

    gdzie (aR,aG,aB) = black = (0,0,0)do cieniowania i (aR,aG,aB) = white = (255,255,255)do barwienia

  • HSVlub HSB:

    • Aby zacieniać: zmniejsz Value/ Brightnesslub zwiększSaturation
    • Aby zabarwić: zmniejsz Saturationlub zwiększ Value/Brightness
  • HSL:
    • Aby zacienić: opuść Lightness
    • Aby zabarwić: zwiększ Lightness

Istnieją formuły do ​​konwersji z jednego modelu kolorów na inny. Zgodnie z początkowym pytaniem, jeśli jesteś w RGBgrze i chcesz na przykład użyć HSVmodelu do cieniowania, możesz po prostu przekonwertować na HSV, wykonać cieniowanie i przekonwertować z powrotem na RGB. Formuły do ​​konwersji nie są trywialne, ale można je znaleźć w Internecie. W zależności od języka może być również dostępna jako funkcja podstawowa:

Porównanie modeli

  • RGB ma tę zaletę, że jest naprawdę łatwy do wdrożenia, ale:
    • możesz tylko odcień lub zabarwić swój kolor względnie
    • nie masz pojęcia, czy Twój kolor jest już zabarwiony czy cieniowany
  • HSVlub HSBjest trochę skomplikowane, ponieważ musisz grać z dwoma parametrami, aby uzyskać to, czego chcesz ( Saturation& Value/ Brightness)
  • HSL jest najlepszy z mojego punktu widzenia:
    • obsługiwane przez CSS3 (dla aplikacji internetowej)
    • proste i dokładne:
      • 50% oznacza niezmieniony odcień
      • >50% oznacza, że ​​odcień jest jaśniejszy (odcień)
      • <50% oznacza, że ​​odcień jest ciemniejszy (odcień)
    • biorąc pod uwagę kolor, możesz określić, czy jest już zabarwiony, czy cieniowany
    • możesz zabarwić lub odcień koloru względnie lub całkowicie (po prostu wymieniając Lightnessczęść)

JBE
źródło
1
Wierzę w to, że „Odcień powstaje przez„ przyciemnienie ”odcienia , przez barwę, masz na myśli kolor. Ponieważ jeśli mówisz o odcieniu, jak w HSL / HSV, zmiana go spowoduje powstanie innego koloru, a nie odcienia / odcienia. Odcień (0-360 °) sam w sobie nie może być ciemniejszy / jaśniejszy. Aby nadać kolor / odcień, należałoby zmodyfikować wartości SL / SV. Ta definicja może skłonić kogoś do myślenia, że ​​zmiana odcienia spowoduje powstanie ciemniejszego / jaśniejszego koloru.
akinuri
Wersja z cieniem działa tylko dla zakresu kolorów zaczynającego się od 0. Dodaj połowę zakresu kolorów do wartości kanału koloru, a następnie wykonaj obliczenia, a następnie odejmij ponownie ten zakres. Jeśli twój kolor jest podpisany i możesz wykonać obliczenia bez niszczenia czegoś z powodu przepełnienia, działa to zgodnie z przeznaczeniem.
t0b4cc0
3

Obecnie eksperymentuję z płótnem i pikselami ... Uważam, że ta logika działa lepiej.

  1. Użyj tego, aby obliczyć szarość (luma?)
  2. ale z istniejącą wartością i nową wartością „odcienia”
  3. obliczyć różnicę (stwierdziłem, że nie muszę mnożyć)
  4. dodaj, aby zrównoważyć wartość „tinty”

    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;
    

czy jakoś tak...

Blair
źródło