Generazione di gradienti RGB


18

La sfida

Date le due stringhe esadecimali maiuscole (lungo entrambi i 6 caratteri, XXXXXX e YYYYYY) che rappresentano valori RGB (da 000000a FFFFFFcompreso), ed una non-zero intero positivo N, mostrano una transizione lineare dei + 2 colori N generati da XXXXXX a YYYYYY ciò comporterebbe una sfumatura di colore.

Esempio

Ingresso

FF3762
F08800
9

Produzione

Nel nostro esempio, ho richiesto 9 passaggi intermedi tra i due colori, quindi verranno visualizzate 11 righe dal colore iniziale al colore finale

FF3762
FD3F58
FC474E
FA4F44
F9573A
F75F31
F66727
F46F1D
F37713
F17F09
F08800

Avvertenze

Mentre ho seguito un semplice processo lineare per derivare i valori interi per i colori provvisori prima di riconvertirli in esadecimali, i tuoi metodi possono variare. Si prega di considerare i vari modi in cui si potrebbero arrotondare i numeri di conseguenza.

analisi

Per rendere questo interessante, ho fornito uno snippet per consentire il test del tuo codice, incluso un pulsante per fornirti due colori casuali per testare il tuo codice. La visualizzazione dei risultati è facoltativa, ma è incoraggiata!

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) Puoi accedere a due colori casuali per il tuo test facendo clic sul pulsante "I tuoi due colori". 2) Il numero di passaggi intermedi sarà lo stesso del numero di caratteri nel tuo nome utente PPCG comprensivo di spazi, nel caso di "WallyWest" sarebbe 9 (come nel mio esempio sopra). 3) Esegui il tuo codice con i due colori e il numero e una volta che hai il tuo elenco generato, hai la possibilità di incollare il tuo output nell'area di testo e di separarlo da esso per ottenere il gradiente di colore generato.

Il mio esempio è mostrato qui:

Sfumature

Devo ammetterlo, sembra davvero fantastico!

Nota: come ho già detto, mostrare il test dell'output utilizzando lo snippet è facoltativo, ma è incoraggiato! :)

Produzione

L'output dell'elenco deve essere sotto forma di set N + 2 di numeri esadecimali a 6 cifre separati da avanzamenti di riga (\ n) come mostrato nel mio esempio sopra. L'output può essere sotto forma di righe separate, elenco separato da spazio / virgola, un array o qualsiasi altra cosa sia più adatta alla tua lingua ... (Grazie @nimi per l'heads up) Ricorda che se hai intenzione di testare il tuo codice con lo snippet, comunque separi ogni "colore" dipende da te.

Regole

Questo è code-golf, quindi la soluzione più breve in byte sarà incoronata vincitrice. Niente scappatoie , naturalmente. L'input deve accettare le due stringhe e un numero (che come ho detto sarà equivalente al numero di lettere nel tuo nome utente su PPCG, quindi l'output risultante sarà sempre lungo almeno tre righe.



Notato e aggiornato ... Grazie per l'heads up (+1)
WallyWest

Per curiosità, le app di immagini come Illustrator usano gradienti lineari o gradienti in uno spazio cromatico percettivo? Riesco a vedere casi d'uso per entrambi (forse stai facendo la trasformazione in percettivo in seguito, ad esempio una trama per un gioco).
Robert Fraser,

Risposte:


1

MATL , 31 byte

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

Questo utilizza l'interpolazione lineare con arrotondamento per difetto. Il formato di input è

9
FF3762
F08800

Provalo online!

Uscita grafica, 31 byte

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

Questo è il risultato per gli input

5
FF3762
F08800

inserisci qui la descrizione dell'immagine

Provalo in MATL online ! L'interprete è attualmente sperimentale. Se non si ottiene alcun output, aggiornare la pagina e premere nuovamente "Esegui".


4

JavaScript (ES6), 130 byte

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>


3

Dyalog APL , 44 byte

Richiede N , quindi B eginning-color, quindi E nding-color. Necessità ⎕IO←0che è predefinita su molti sistemi.

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

h[... ]indice in h (che ha un valore quando finiamo di valutare il contenuto della parentesi)

N←⎕richiesta numerica N (4)

1+aggiungine uno a N (5)

(... usalo per dividere il risultato di ...

  ⍞⍞ richiesta di due stringhe di caratteri ["7E0E7E", "FF3762"]

  (... )∘⍳¨trova gli indici dei caratteri di ogni stringa in ...

   ⎕D,⎕A D igits seguita da un alfabeto

   h←assegnato a h

  ora abbiamo "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  E B←assegnare gli indici a E e B [[7,14,0,14,7,14], [15,15,3,7,6,2]]

  -/sottrarre e racchiudere B da E [[-8, -1, -3,7,1,12]]

  il risultato finora è [[-1.6, -0.2, -0.6,1.4,0.2,2.4]]

(... moltiplicalo per ...

  2+Ndue più N (6)

   primi numeri interi [0,1,2,3,4,5]

 questo ci dà [[0,0,0,0,0,0], [- 1,6, -0,2, -0,6,1,4,0,2,2,4], [- 3,2, -0,4, -1,2,2,8,0,4,4,8 ], ...]

B∘+¨aggiungere B a ciascuno [[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], ... ]

arrotondato per difetto [[15,15,3,7,6,2], [13,14,2,8,6,4], [11,14,1,9,6,6], ...]

fare una lista di liste in tabella

[[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]]

qui indicizziamo in h , dando

[["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]]

che è lo stesso di

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

e stampa come

FF3762
DE2864
BE1966
AE1B69
8E0C6B
7E0E7E

pendenza

ProvaAPL online!


Bel lavoro! La transizione sembra fantastica!
WallyWest,

@WallyWest Grazie. Probabilmente si tratta di una transizione lineare diversa rispetto alla maggior parte delle altre: ogni lettera viene trasferita separatamente.
Adám,

2

Pyth - 35 byte

Orribilmente golf, ha appena rinunciato.

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

Provalo online qui .

Esempio:

esempio


Conto 11 righe di gradiente, anche se il tuo nome PPCG ha solo 8 lettere ... Quindi non dovresti aver inserito 7cb472 93fb8a 8e ricevuto solo 10 righe di output durante il test del tuo codice?
WallyWest,

@WallyWest ha completamente perso quella parte nell'OP sul nome utente, ho appena usato 9 perché l'hai fatto, riparando.
Maltysen,

@WallyWest aggiornato
Maltysen

Ehi @Maltysen, il gradiente sembra un po 'strano ... hai due riferimenti a 93fb8a... Il tuo codice ha prodotto due righe dello stesso valore?
WallyWest,

2

PowerShell v2 +, 176 159 150 byte

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))})}

Prende l'input come due stringhe e un numero, quindi converte la stringa di inizio in una matrice di stringhe suddivisa su ogni due caratteri, la memorizza in $x. Quindi eseguiamo l' output $acome sezione iniziale e eseguiamo il loop da ++$na 1(per garantire una corretta recinzione).

Ogni iterazione, imposta l'helper $jsul numero corrente (utilizzato in seguito per garantire che abbiamo il giusto numero di passaggi tra il punto in cui ci troviamo attualmente alla nostra destinazione) e calcola il passaggio successivo in base a un loop through $x.

Ogni ciclo interno è solo un compito. Stiamo impostando $xnel punto appropriato uguale a una nuova stringa "{0:x2}"usando l' -foperatore ormat. Il x2qui specifica un'uscita esadecimale di due cifre, e l'ingresso è il lato destro del -foperatore. PowerShell ha un operatore esadecimale-decimale nativo 0x, quindi questa lunga espressione annidata tra parentesi sta usando quell'operatore per convertire l'esagono corrente in numeri, sottraendo per trovare la differenza ancora da fare (fatto dividendo dinamicamente $bqui proprio come abbiamo fatto $a, e usando il modulo per selezionare l'elemento giusto), dividendo per i $jpassaggi rimanenti, passando a un[int] (PowerShell esegue l'arrotondamento del banco per impostazione predefinita) e sottraendo quel conteggio dei passi dall'esagono corrente per ottenere quello che deve essere il nostro esagono successivo.

Il risultato di quel calcolo viene memorizzato nuovamente in $xtre elementi esadecimali. Questo è incapsulato in parentesi per creare una copia sulla pipeline ed -joineditato insieme in una singola stringa. Tutte le stringhe risultanti vengono lasciate sulla pipeline e l'output tramite implicito Write-Outputavviene durante l'esecuzione del programma.


Esempio

Mi hanno dato 0ba7c5 e 6c0e50 per i miei due colori e TimmyD ha 6 caratteri.

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

Esempio di sfumatura


1

Python 2, 189 byte

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)

screenshot del gradiente


Splendida coppia di colori, @AndrewEpstein ... Bel lavoro con il codice!
WallyWest,

1

[Groovy] Aggiornamento finale (199 byte) - Come da richiesta

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()}}

Prova qui la finale: https://groovyconsole.appspot.com/script/5130696796405760


VECCHIE VERSIONI SOTTO, DECLINATE DALL'OP


Groovy (123 byte)

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))]
  }
}

ingressi

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

Esempio di output

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

risultati in

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

Provalo tu stesso: https://groovyconsole.appspot.com/script/5184465357766656

Con conversioni esadecimali incluse

Immagino che sia un po 'anche barare ... Ecco lo script con l'utilizzo di hex:

Nuovo codice con conversioni esadecimali:

​    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 caratteri quando golfati:

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))))}}

Uscita da 000000 a FFFFFF e 16 (Lunghezza nome utente)

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

Sfumatura monocromatica con incrementi di 1/16


Err ... leggermente non valido, versione originale utilizzata "(0 .. (1.0 / s))", avrebbe dovuto essere "(1 .. (1.0 / s))".
Magic Octopus Urn

1
Ciao @carusocomputing ... L'input deve essere di due stringhe esadecimali e un numero intero ... Non sono sicuro che Groovy possa accettare input in questo modo, ma non hai ancora delineato il brief ... Potresti aggiornare il tuo codice basato sull'input menzionato nella sezione Challenge?
WallyWest,

{s-> s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}}('FFFFFF') Risultati in [255,255,255] Posso aggiungere 62 byte al mio codice usando quella conversione se lo vuoi davvero.
Magic Octopus Urn

1
Wally, ho aggiunto una versione aggiornata e ho aumentato il mio conteggio di byte finale a 199 con conversioni incluse.
Magic Octopus Urn

1

R, 68 byte

C'è una funzione integrata che interpola due colori:

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

Ingresso:

d9e7a5
3ef951
15

Output: un vettore con valori

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

La specifica del colore in R richiede un simbolo hash.

Rampa di colore

Tracciamo qualcosa, come una funzione:

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)


Ottima risposta, ma il brief chiede di usare tutti i passaggi del nome utente PPCG, che contando lo spazio fa 15 ... Potresti aggiornare la tua risposta in base FF3762 F08800 15?
WallyWest,

@WallyWest Spiacente, mi ero perso quella parte in cui si ottengono due colori e conta la lunghezza del proprio nome utente. Ora la risposta dovrebbe essere pienamente conforme alle specifiche!
Andreï Kostyrka,

1

C, 175 169 168 byte

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););}

Ungolfed:

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("");
  }
}

Grazie a @ h-walters per la rasatura di 5 byte!


Ricordami cosa putsfa di nuovo la sintassi?
WallyWest,

È come printf(), ma non esegue alcuna formattazione, invece stampa semplicemente la stringa data così com'è e aggiunge una nuova riga.
G. Sliepen,

Ah, quindi non c'è modo di giocare a golf che ... C è un po 'restrittivo in quel modo, no?
WallyWest,

"quindi non c'è modo di giocare a golf" ... Certo che c'è! Passa puts("")alla terza parte del primo per il ciclo (il ;dopo diventa un ,precedente) ... +0 byte. Tuttavia, ciò consente di rimuovere le parentesi graffe dopo il secondo ciclo ... -2 byte. Puoi salvare un altro 1 byte rimuovendo 3 da j<3e sostituendolo con la tua printfdichiarazione (questo è subdolo ... printf restituirà solo 2, ma deve ancora valutare la terza volta).
H Walters,

... altri due byte possono essere salvati sottraendo i valori restituiti da sscanf l'uno dall'altro (risultando in 0) e usando quello al posto del letterale 0in j=0. Una volta che tutto è a posto, il programma dovrebbe essere più corto di 5 byte e almeno il 50% più sconosciuto.
H Walters,

1

sh + ImageMagick, 81 byte

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

utilizzo:

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

("-depth 8" non è necessario se il tuo IM è compilato con 8bpp come predefinito)

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.