Generowanie gradientów RGB

18

Wyzwanie

Biorąc pod uwagę dwa wielkie ciągi szesnastkowe (oba o długości 6 znaków, XXXXXX i RRRRRR) reprezentujące wartości RGB (od 000000do FFFFFFwłącznie) oraz dodatnią niezerową liczbę całkowitą N, wyświetl liniowe przejście kolorów N + 2 wygenerowanych z XXXXXX na RRRRRR spowoduje to gradient kolorów.

Przykład

Wejście

FF3762
F08800
9

Wynik

Uwaga: w naszym przykładzie poprosiłem o 9 pośrednich kroków między dwoma kolorami, dlatego 11 linii zostanie wyświetlonych od koloru początkowego do koloru końcowego

FF3762
FD3F58
FC474E
FA4F44
F9573A
F75F31
F66727
F46F1D
F37713
F17F09
F08800

Ostrzeżenia

Chociaż przeszedłem prosty liniowy proces wyprowadzania wartości liczb całkowitych dla kolorów tymczasowych przed przekształceniem ich z powrotem w szesnastkowy, twoje metody mogą się różnić. Proszę rozważyć różne sposoby odpowiedniego zaokrąglania liczb w górę / w dół .

Testowanie

Aby uczynić to interesującym, udostępniłem fragment kodu umożliwiający testowanie kodu, w tym przycisk zapewniający dwa losowe kolory do testowania kodu. Wyświetlanie wyników jest opcjonalne, ale zalecane!

c1=()=>('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6);

$("#col").click(function(){
  alert("Your two colors are: "+c1()+" and "+c1()+".");
});
        
$("#colors").blur(function(){
  $("#test").empty();
	var colArr = $("#colors").val().split("\n");
	for(c in colArr){
  	$("#test").append('<div class="tester" style="background-color:#'+colArr[c]+';">'+colArr[c]+'</div>')
  }
  
});
.tester{height: 20px;
width: 60px;padding: 4px;border: 1px solid black;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="col">Your two colors</button><br />
<textarea id="colors"></textarea>
<div id="test">

</div>

1) Możesz uzyskać dostęp do dwóch losowych kolorów do testu, klikając przycisk „Twoje dwa kolory”. 2) Liczba kroków pośrednich będzie taka sama jak liczba znaków w nazwie użytkownika PPCG łącznie ze spacjami, w przypadku „WallyWest” będzie to 9 (jak w moim przykładzie powyżej). 3) Uruchom kod z dwoma kolorami i liczbą, a kiedy już utworzysz listę, możesz wkleić dane wyjściowe do obszaru tekstowego i tabulować je, aby uzyskać wygenerowany gradient kolorów.

Mój przykład pokazano tutaj:

Gradienty

Muszę przyznać, że wygląda to niesamowicie!

Uwaga: jak już wspomniałem, pokazanie testowania wyników za pomocą fragmentu kodu jest opcjonalne, ale zalecane! :)

Wynik

Dane wyjściowe listy muszą mieć postać N + 2 zestawów 6-cyfrowych liczb szesnastkowych oddzielonych wierszami (\ n), jak pokazano w moim przykładzie powyżej. Wyjście może być w formie oddzielnych linii, przestrzeń / oddzielonych przecinkami listę, tablicą lub cokolwiek jest najlepsza dla danego języka ... (Dzięki @nimi do głów w górę) Proszę pamiętać, że jeśli plan testowania kodu z fragment kodu, niezależnie od tego, jak rozdzielisz każdy „kolor”, zależy od Ciebie.

Zasady

To jest golf golfowy, więc zwycięzca otrzyma najkrótsze rozwiązanie w bajtach. Naturalnie brak luk . Dane wejściowe muszą akceptować dwa ciągi i liczbę (która, jak powiedziałem, będzie równoważna liczbie liter w nazwie użytkownika na PPCG, a zatem wynikowy wynik zawsze będzie miał co najmniej trzy linie.

WallyWest
źródło
Zauważono i zaktualizowano ... Dzięki za heads-up (+1)
WallyWest,
Z ciekawości, czy aplikacje graficzne, takie jak Illustrator, używają gradientów liniowych lub gradientów w jakiejś percepcyjnej przestrzeni kolorów? Widzę przypadki użycia dla obu (być może robisz transformację do percepcji później, np. Teksturę do gry).
Robert Fraser,

Odpowiedzi:

1

MATL , 31 bajtów

2+1yhjjh2e!1ZA3e!b:1&Ynk8W5Y2Za

Wykorzystuje interpolację liniową z zaokrąglaniem w dół. Format wejściowy to

9
FF3762
F08800

Wypróbuj online!

Wyjście graficzne, 31 bajtów

2+1yhjjh2e!1ZA3e!b:t2YG1&Ynk2ZG

Jest to wynik dla danych wejściowych

5
FF3762
F08800

wprowadź opis zdjęcia tutaj

Wypróbuj w MATL Online ! Tłumacz jest obecnie w fazie eksperymentalnej. Jeśli nie otrzymasz żadnych wyników, odśwież stronę i ponownie naciśnij „Uruchom”.

Luis Mendo
źródło
4

JavaScript (ES6), 130 bajtów

g=
(f,t,n)=>[...Array(++n+1)].map((_,i)=>f.replace(/../g,(e,j)=>((`0x${e}`*(n-i)+`0x${t[j]+t[j+1]}`*i)/n|256).toString(16).slice(1)))
;
p=_=>g(f.value,t.value,+n.value).map(e=>o.insertRow().insertCell().appendChild(document.createTextNode(e)).parentNode.bgColor=e);
<input id=f value=e14f09><input id=t value=9a04f6><input id=n value=4 type=number><input type=button onclick=p() value=Go!><table id=o bgcolor=black cellpadding=4>

Neil
źródło
3

Dyalog APL , 44 bajty

Zachęty do N , a B eginning przebarwień, to E nding kolorze. Potrzeby, ⎕IO←0które są domyślne w wielu systemach.

h[↑⌊B∘+¨(⍳2+N)×(-/E B←(h←⎕D,⎕A)∘⍳¨⍞⍞)÷1+N←⎕]

h[... ]indeksuj w h (która ma wartość, gdy skończymy oceniać zawartość nawiasu)

N←⎕ monit o numeryczne N (4)

1+ dodaj jeden do N (5)

(... użyj tego, aby podzielić wynik ...

  ⍞⍞ monit o dwa ciągi znaków [„7E0E7E”, „FF3762”]

  (... )∘⍳¨znajdź indeksy znaków każdego ciągu w ...

   ⎕D,⎕A D igits, po których następuje A alfabet

   h← przypisane do h

  teraz mamy „0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ”

  E B←przypisz wskaźniki do E i B [[7,14,0,14,7,14], [15,15,3,7,6,2]]

  -/odejmij i załącz B z E [[-8, -1, -3,7,1,12]]

  dotychczasowy wynik to [[-1,6, -0,2, -0,6,1,4,4,0,2,2,4]]

(... pomnóż to przez ...

  2+Ndwa plus N (6)

   pierwsze liczby całkowite [0,1,2,3,4,5]

 daje nam to [[0,0,0,0,0,0,0], [- 1,6, -0,2, -0,6,1,4,4,0,2,2,4], [- 3,2, -0,4, -1,2,2.8,0.4,4.8 ], ...]

B∘+¨dodać B do każdego [[15,15,3,7,6,2], [13.4,14.8,2.4,8.4,6.2,4.4], [11.8,14.6,1.8,9.8,6.4,6.8], ... ]

zaokrąglić w dół [[15,15,3,7,6,2], [13,14,2,8,6,4], [11,14,1,9,6,6], ...]

zrobić listę list w tabeli

[[15,15, 3, 7, 6, 2]
 [13,14, 2, 8, 6, 4]
 [11,14, 1, 9, 6, 6]
 [10,14, 1,11, 6, 9]
 [ 8,14, 0,12, 6,11]
 [ 7,14, 0,14, 7,14]]

tutaj indeksujemy do h , dając

[["F","F","3","7","6","2]
 ["D","E","2","8","6","4]
 ["B","E","1","9","6","6]
 ["A","E","1","B","6","9]
 ["8","E","0","C","6","B]
 ["7","E","0","E","7","E]]

który jest taki sam jak

[["FF3762"]
 ["DE2864"]
 ["BE1966"]
 ["AE1B69"]
 ["8E0C6B"]
 ["7E0E7E"]]

i drukuje jako

FF3762
DE2864
BE1966
AE1B69
8E0C6B
7E0E7E

gradient

Wypróbuj APL online!

Adám
źródło
Dobra robota! Przejście wygląda świetnie!
WallyWest,
@WallyWest Thanks. Prawdopodobnie jest to inne przejście liniowe niż większość: Każda litera jest przenoszona osobno.
Adám
2

Pyth - 35 bajtów

Okropnie grał w golfa, po prostu się poddał.

j++hQsMCm.HMsM:F+dc-FdvzCmiR16cd2Qe

Wypróbuj online tutaj .

Przykład:

przykład

Maltysen
źródło
Naliczyłem 11 linii gradientu, chociaż twoja nazwa PPCG ma tylko 8 liter ... Więc nie powinieneś był wprowadzać 7cb472 93fb8a 8i otrzymywać tylko 10 linii wyniku podczas testowania kodu?
WallyWest,
@WallyWest całkowicie pominął tę część OP dotyczącą nazwy użytkownika, właśnie użyłem 9, ponieważ zrobiłeś, naprawianie.
Maltysen
@WallyWest updated
Maltysen
Hej @Maltysen, gradient wydaje się nieco dziwny ... masz dwa odniesienia 93fb8a... Czy twój kod wyprowadził dwa wiersze o tej samej wartości?
WallyWest,
2

PowerShell v2 +, 176 159 150 bajtów

param($a,$b,$n)$x=$a-split'(..)'-ne'';$a;++$n..1|%{$j=$_;-join($x=$x|%{"{0:x2}"-f(+"0x$_"-[int]((+"0x$_"-"0x$(($b-split'(..)'-ne'')[$i++%3])")/$j))})}

Pobiera dane wejściowe jako dwa ciągi i liczbę, a następnie przekształca ciąg początkowy w tablicę ciągów podzieloną na każde dwa znaki, zapisuje to w $x. Następnie wyprowadzamy dane wyjściowe $ajako sekcję początkową i zapętlamy od ++$ndo 1(aby zapewnić prawidłowe ustawienie ogrodzenia).

Każda iteracja ustawia pomocnika $jna bieżącą liczbę (używaną później w celu upewnienia się, że mamy odpowiednią liczbę kroków między miejscem, w którym aktualnie jesteśmy do celu) i oblicza następny krok na podstawie pętli$x .

Każda wewnętrzna pętla jest tylko zadaniem. Jesteśmy ustawienie $xw odpowiednim miejscu równa nowego łańcucha "{0:x2}"przy użyciu -foperatora Ormat. x2Tutaj określa dwucyfrową wyjście szesnastkowy, a wejście jest po prawej stronie od -foperatora. PowerShell ma natywny operator szesnastkowy do dziesiętnego 0x, więc to długie wyrażenie zagnieżdżone w parens używa tego operatora do konwersji bieżącego heksadecymalnego na liczby, odejmując, aby znaleźć różnicę, która jeszcze nie została wykonana (dokonane przez dynamiczne dzielenie $btutaj, tak jak to zrobiliśmy $a, i używając modulo, aby wybrać odpowiedni element), dzieląc przez $jpozostałe kroki, rzutując na an[int] (PowerShell domyślnie zaokrągla bankiera) i odejmuje tę liczbę kroków od bieżącego heksa, aby uzyskać to, co powinno być naszym następnym heksem.

Wynik tego obliczenia jest przechowywany z powrotem w $xpostaci trzech elementów szesnastkowych. Jest to zamknięte w parens, aby utworzyć kopię w potoku, i -joinpołączone razem w jeden ciąg. Wszystkie te łańcuchy wynikowe są pozostawione w potoku, a dane wyjściowe za pośrednictwem niejawnego mają Write-Outputmiejsce podczas wykonywania programu.


Przykład

Dostałem 0ba7c5 i 6c0e50 za moje dwa kolory, a TimmyD ma w nim 6 znaków.

PS C:\Tools\Scripts\golfing> .\rgb-gradients-generation.ps1 '0ba7c5' '6c0e50' 6
0ba7c5
1991b4
277ba3
356592
434f82
513971
5f2361
6c0e50

Przykład gradientu

AdmBorkBork
źródło
1

Python 2, 189 bajtów

w='[int(%s[i:i+2],16)for i in range(0,6,2)]'
def f(a,b,n):
 l=lambda x,y:'%02x'%int((x*(n-i)+y*i)/n);c,d,e=eval(w%'a');f,g,h=eval(w%'b');n+=1
 for i in range(n+1):print l(c,f)+l(d,g)+l(e,h)

zrzut ekranu gradientu

Andrew Epstein
źródło
Wspaniała para kolorów, @AndrewEpstein ... Dobra robota z kodem!
WallyWest,
1

[Groovy] Ostatnia aktualizacja (199 bajtów) - zgodnie z życzeniem

Non-golf

def g(a,b,n){
  (0..(1.0/n)).collect{
    c->
    x={s->s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}};
    (0..2).collect {
      (int)(x(a).get(it)*n*c+x(b).get(it)*(1-n*c))
    }.collect {
      String.format("%X", it)
    }.join()
  }
}
g('FFFFFF','000000',1/10​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​)​​​​​​​​​​​​​​

Golf

g(a,b,n){(0..(1.0/n)).collect{c->x={s->s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}};(0..2).collect {(int)(x(a).get(it)*n*c+x(b).get(it)*(1-n*c))}.collect{String.format("%X",it)}.join()}}

Wypróbuj finał tutaj: https://groovyconsole.appspot.com/script/5130696796405760


PONIŻSZE WERSJE STARE, ODRZUCONE PRZEZ OP


Groovy (123 bajtów)

Golf

def g(r,g,b,r2,g2,b2,s){(1..(1.0/s)).collect{c->[(int)(r*s*c+r2*(1-s*c)),(int)(g*s*c+g2*(1-s*c)),(int)(b*s*c+b2*(1-s*c))]}}

Non-golf

def g(r,g,b,r2,g2,b2,s){
  (1..(1.0/s)).collect {
    c ->
    [(int)(r*s*c+r2*(1-s*c)),(int)(g*s*c+g2*(1-s*c)),(int)(b*s*c+b2*(1-s*c))]
  }
}

Wejścia

r,g,b -> Starting RGB Color
r2,g2,b2 -> Ending RGB Color
s -> Gradient step

Przykład wyjścia

(00,00,00,255,255,255,.5)

prowadzi do

[
  [255, 255, 255]
  [127, 127, 127]
  [0, 0, 0]
]

Wypróbuj sam: https://groovyconsole.appspot.com/script/5184465357766656

Z dołączonymi konwersjami szesnastkowymi

Chyba też trochę oszukuję ... Oto skrypt z użyciem hexa:

Nowy kod z konwersjami szesnastkowymi:

​    def g(r,g,b,r2,g2,b2,s){
      (0..(1.0/s)).collect {
        c ->
        String.format("%X", ((int)(r*s*c+r2*(1-s*c)))) +  String.format("%X", ((int)(g*s*c+g2*(1-s*c)))) + "" +  String.format("%X", ((int)(b*s*c+b2*(1-s*c))))
      }
    }

    g(126,34,166,218,26,33,0.0625)​

188 znaków podczas gry w golfa:

def g(r,g,b,r2,g2,b2,s){(0..(1.0/s)).collect {c->String.format("%X",((int)(r*s*c+r2*(1-s*c))))+String.format("%X",((int)(g*s*c+g2*(1-s*c))))+String.format("%X",((int)(b*s*c+b2*(1-s*c))))}}

Wyjście dla 000000 do FFFFFF i 16 (długość nazwy użytkownika)

g(00,00,00,255,255,255,0.0625).each{println it}​

Gradient monochromatyczny z krokiem 1/16

Urna Magicznej Ośmiornicy
źródło
Err ... nieco niepoprawna, w oryginalnej wersji użyto „(0 .. (1,0 / s))”, powinno być „(1 .. (1,0 / s))”.
Magic Octopus Urn
1
Cześć @carusocomputing ... Dane wejściowe muszą składać się z dwóch ciągów szesnastkowych i liczby całkowitej ... Nie jestem pewien, czy Groovy może przyjmować dane w ten sposób, ale nie udało ci się w pełni przyswoić instrukcji ... Czy możesz zaktualizować twój kod na podstawie danych wejściowych wymienionych w sekcji Wyzwanie?
WallyWest,
{s-> s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}}('FFFFFF') Wyniki w [255,255,255] Mogę dodać 62 bajty do mojego kodu za pomocą tej konwersji, jeśli naprawdę tego chcesz.
Magic Octopus Urn
1
Wally, dodałem zaktualizowaną wersję i podniosłem końcową liczbę bajtów do 199 z uwzględnieniem konwersji.
Magic Octopus Urn
1

R, 68 bajtów

Istnieje wbudowana funkcja interpolująca dwa kolory:

a=scan(,'')
colorRampPalette(paste0("#",a[1:2]))(as.numeric(a[3])+2)

Wejście:

d9e7a5
3ef951
15

Wyjście: wektor z wartościami

"#D9E7A5" "#CFE89F" "#C5E99A" "#BBEA95" "#B2EB90" "#A8EC8A" "#9EED85" "#95EE80"
"#8BF07B" "#81F175" "#78F270" "#6EF36B" "#64F466" "#5BF560" "#51F65B" "#47F756"
"#3EF951"

Specyfikacja kolorów w R wymaga symbolu skrótu.

Kolorowa rampa

Narysujmy coś, na przykład funkcję:

filled.contour(outer(1:20, 1:20, function(x,y) sin(sqrt(x*y)/3)),
    col = colorRampPalette(paste0("#",a[1:2]))(as.numeric(a[3])+2))

sin (sqrt (x * y) / 3)

Andreï Kostyrka
źródło
Świetna odpowiedź, ale w tym skrócie prosi się o podanie tylu kroków, ile jest w nazwie użytkownika PPCG, co zliczając miejsce zajmuje 15 ... Czy możesz zaktualizować swoją odpowiedź na podstawie FF3762 F08800 15?
WallyWest
@WallyWest Przepraszamy, tęskniłem za tą częścią, w której jeden uzyskuje dwa kolory i liczy swoją własną nazwę użytkownika. Teraz odpowiedź powinna być w pełni zgodna ze specyfikacją!
Andreï Kostyrka
1

C, 175 169 168 bajtów

i;j;x[6];f(a,b,n)char*a,*b;{char*f="%2x%2x%02x";for(n++;i<=n;i++,puts(""))for(j=sscanf(a,f,x,x+1,x+2)-sscanf(b,f,x+3,x+4,x+5);j++<printf(f+6,x[j]+(x[j+3]-x[j])*i/n););}

Nie golfowany:

int i, j;
int x[3], y[3];

f(char *a, char *b, int n) {
  sscanf(a, "%2x%2x%2x", &x[0], &x[1], &x[2]);
  sscanf(b, "%2x%2x%2x", &y[0], &y[1], &y[2]);

  for(i = 0, n++; i <= n; i++) {
    for(j = 0; j < 3; j++)
      printf("%02x", x[j] + (y[j] - x[j]) * i / n);
    puts("");
  }
}

Dzięki @ h-walters za golenie 5 bajtów!

G. Sliepen
źródło
Przypomnij mi, co putsrobi składnia ponownie?
WallyWest
Jest jak printf(), ale nie wykonuje żadnego formatowania, zamiast tego po prostu drukuje podany ciąg znaków i dodaje nowy wiersz.
G. Sliepen
Ach, więc nie ma sposobu na grę w golfa, że ​​... C jest trochę tak restrykcyjne, prawda?
WallyWest
„więc nie ma sposobu na grę w golfa, że”… Pewnie, że jest! Przejdź puts("")do trzeciej części pierwszej pętli for ( ;po stanie się ,wcześniej) ... +0 bajtów. Pozwala to jednak usunąć nawiasy klamrowe po drugiej pętli ... -2 bajty. Możesz zapisać kolejny 1 bajt, usuwając 3 z j<3i zastępując go printfinstrukcją (jest to podstępne ... printf zwróci tylko 2, ale nadal musi oceniać po raz trzeci).
H Walters,
... dwa kolejne bajty można zapisać, odejmując od siebie wartości zwracane przez sscanf (w wyniku 0) i używając tego zamiast literału 0w j=0. Gdy wszystko tu będzie na swoim miejscu, twój program powinien być o 5 bajtów krótszy i co najmniej 50% dziwniejszy.
H Walters,
1

sh + ImageMagick, 81 bajtów

convert -size 1x$((2+$3)) gradient:#$1-#$2 -depth 8 txt:-|grep -o "[A-F0-9]\{6\}"

stosowanie:

> ./grad.sh FF3762 F08800 9
FF3762
FE3F58
FC474E
FB4F45
F9573B
F86031
F66827
F5701D
F37814
F2800A
F08800

(„-depth 8” nie jest konieczne, jeśli twój IM jest skompilowany z domyślną wartością 8bpp)

Sparr
źródło