Generowanie serii kolorów między dwoma kolorami

15

Biorąc pod uwagę kolor początkowy i końcowy, czy możliwe jest algorytmiczne generowanie zakresu kolorów między nimi? Na przykład, biorąc pod uwagę jasne i ciemne odcienie niebieskiego / szarego na początku i na końcu obrazka poniżej, jak mogę wygenerować odcienie pośrednie?

wprowadź opis zdjęcia tutaj

Jednym z możliwych rozwiązań, które rozważam, jest utworzenie gradientu z dwóch kolorów, a następnie próbkowanie koloru w równo odległych punktach wzdłuż tego gradientu. Czy to może być najlepsze podejście?

Ben Packard
źródło
2
Spójrz na to: graphicdesign.stackexchange.com/questions/75417/... Czy to może być ducplicate?
Rafael
Kolejny dobry artykuł na ten temat: vis4.net/blog/posts/avoid-equidistant-hsv-colors
cierń
Jest to bardzo bliskie bycia duplikatem tego pytania o przepełnienie stosu
Dawood mówi, że przywróć Monikę

Odpowiedzi:

13

Nazywa się to interpolacją kolorów . To właśnie robią gradienty pod maską. Możesz to zrobić przy użyciu różnych środków i metod, a dokładny sposób interpolacji wyników zależy od metody.

Zazwyczaj robię to dla projektów internetowych przy użyciu JavaScript, dzięki czemu mogę dynamicznie zmieniać kolory, na przykład w tym wizualizatorze muzyki . Implementacja JavaScript, która ma bardzo prostą metodę interpolacji liniowej za pomocą RGB, wyciągnięta z powyższego przykładu, wygląda następująco:

Demo na żywo

// Returns a single rgb color interpolation between given rgb color
// based on the factor given; via https://codepen.io/njmcode/pen/axoyD?editors=0010
function interpolateColor(color1, color2, factor) {
    if (arguments.length < 3) { 
        factor = 0.5; 
    }
    var result = color1.slice();
    for (var i = 0; i < 3; i++) {
        result[i] = Math.round(result[i] + factor * (color2[i] - color1[i]));
    }
    return result;
};
// My function to interpolate between two colors completely, returning an array
function interpolateColors(color1, color2, steps) {
    var stepFactor = 1 / (steps - 1),
        interpolatedColorArray = [];

    color1 = color1.match(/\d+/g).map(Number);
    color2 = color2.match(/\d+/g).map(Number);

    for(var i = 0; i < steps; i++) {
        interpolatedColorArray.push(interpolateColor(color1, color2, stepFactor * i));
    }

    return interpolatedColorArray;
}

Który jest używany w ten sposób i zwraca tablicę interpolowanych kolorów:

var colorArray = interpolateColors("rgb(94, 79, 162)", "rgb(247, 148, 89)", 5);

Możesz także znaleźć rozszerzenia PhotoShop (i prawdopodobnie inne programy) do interpolacji kolorów. Możesz jednak sprawdzić, czy metoda interpolacji jest taka sama, jak chcesz, ponieważ możesz użyć dowolnej funkcji do interpolacji na podstawie.

Zach Saucier
źródło
2
Zach ... jesteś takim maniakiem ... że wizualizator muzyki jest świetny!
Rafael
@Rafael Zrobiłem kilka innych, które również mogą ci się spodobać :)
Zach Saucier
Dzięki. Color Interpolationbyło to, czego potrzebowałem. Znalazłem tutaj kilka implementacji Swift - stackoverflow.com/questions/22868182/uico…
Ben Packard
2
Powyższy link jest zepsuty, ale post można znaleźć tutaj dla przyszłych czytelników: Przejście UIColor na podstawie wartości postępu
Zach Saucier
23

Spójrz na tę odpowiedź. Jak sprawić, by dany kolor był nieco ciemniejszy lub jaśniejszy?

Gdzie po prostu bierzesz oddzielne wartości każdego komponentu RGB i dzielisz wartości.

Ale mamy jeden problem, nie ma tylko jednego sposobu na przejście kolorów.

wprowadź opis zdjęcia tutaj

Pierwsze podejście da ci najkrótszą trasę (1), ale prawdopodobnie ta trasa nie jest tym, czego potrzebujesz.

Ma to również wpływ na model kolorów lub logikę. Na przykład w modelu kolorów Lab * czerwony i zielony są kolorami uzupełniającymi się, więc krótka droga na tym modelu będzie przebiegać przez neutralną szarość (3).

Jeśli potrzebujesz tylko odcieni koloru, druga odpowiedź jest odpowiednia.

Rafael
źródło
5
Podoba mi się grafika przedstawiająca różne metody interpolacji
Zach Saucier
To chyba oznacza, że ​​musi istnieć sposób na skodyfikowanie strategii ścieżki.
Bao Thien Ngo
10

Użyj mieszanki w programie Illustrator w RGB lub CMYK:

  • utwórz 2 kształty, każdy w kolorze początkowym i końcowym (jeden szary i jeden czarny w tym przykładzie, ale wybierz to, czego potrzebujesz)
  • przejdź do Object → Blend → Blend Optionsi wpisz, ile Specified stepspotrzebujesz pomiędzy (20 w moim przykładzie poniżej)
  • wybierz dwa obiekty i wybierz Object → Blend → Make. Spowoduje to wygenerowanie połączenia, które można następnie przekształcić w pojedyncze obiekty Object → Expand. Następnie możesz zobaczyć każdy obiekt pośredni z własnym kodem koloru.

mieszanie

Lucian
źródło
5

Jest to dodatek do innych odpowiedzi.

Kiedy interpolujesz kolory w sRGB, musisz wziąć pod uwagę, że wartości RGB nie są liniowe pod względem intensywności światła, ale liniowe pod względem intensywności światła postrzeganego przez człowieka. Ułatwia to zapisywanie wartości, ale w przypadku różnych operacji kolorów konieczne jest przejście do liniowej przestrzeni kolorów.

Ludzka percepcja intensywności światła jest zgodna z prawem mocy, podobnie jak

linear = sRGB^2.2
sRGB = linear^(1/2.2)

można użyć do transformacji między nimi. Wykorzystuje to wartość gamma 2,2, która jest wartością dla sRGB. Więcej informacji na ten temat można znaleźć w tym artykule w Wikipedii.

Szczegółową analizę tego problemu i przykłady niewłaściwych implementacji można znaleźć tutaj . Jednym z nich jest gradient kolorów z wykorzystaniem interpolacji liniowej i sRGB.

henje
źródło
To jedna z metod interpolacji wartości sRGB, ale to, co dana osoba powinna zrobić, zależy od pożądanego efektu
Zach Saucier
Zgadza się, ale interpolacja w przestrzeni liniowej dzieje się ze światłem w prawdziwym życiu. Jest to więc najbardziej naturalne.
henje
1
@ZachSaucier liczbę razy ludzie zrobili interpolacji lub łączenie w sRGB z intencją jest specyficzny oh-tak małe w porównaniu do tego, ile razy ludzie zrobili to z niewiedzy lub lenistwa (albo myśląc, że to robi w RGB lub myślenie (słusznie lub nie), że różnica jest nieistotna).
hobbs
1

Gradient Photoshopa (lub równoważnie „Mieszanie” w Ai) jest już przedstawiany jako sposób na uzyskanie liniowego przejścia kolorów między kolorami początkowym i końcowym. Jak uzyskać coś nieliniowego (zakrzywiona ścieżka przejścia) bez programowania kodu skryptowego?

Jednym z rozwiązań jest modyfikacja ścieżki przejścia gradientu za pomocą warstw dopasowania lub trybów mieszania albo obu. To naprawdę powoduje ciągłą transformację od koloru początkowego do koloru końcowego, jeśli modyfikujące warstwy mają maskę warstwy, która jest ciągła i sprawia, że ​​afekcja = zero na początku i na końcu.

Oto dość złożony zwrot akcji. Warstwa „Sam cel” ma gradient, a warstwa „Modyfikator” powoduje ciągłe przesunięcie koloru przez tryb mieszania „Kolor”. Aby wszystko zakręciło, sam modyfikator jest gradientem.

Większy skręt jest generowany przez warstwę dopasowania „Krzywe”, która dodaje kontrast. Ma tę samą maskę warstwy co modyfikator, ale nie jest to obowiązkowe. Każda maska ​​jest w porządku, jeśli jest ciągła i czarna na początku i na końcu.

Istnieją pewne nieciągłe tryby mieszania i krzywe, które powodują nagły skok. Jednym z nich jest „Hue”. Inną możliwością zepsucia efektu jest „bez zmian”, widoczny stały obszar koloru spowodowany przycinaniem do zera lub wszystkich 255. Nie testowałem ani nie obliczałem, ile to w praktyce pomaga w użyciu trybu RGB 48 bitów / piksel. Może wcale nie, ponieważ wciąż mamy tylko 24 bity / piksel na ekranie.

Przejście

użytkownik 287001
źródło