Generación de gradientes RGB


18

El reto

Teniendo en cuenta las dos cadenas hexadecimales en mayúsculas (ambos 6 caracteres de largo, XXXXXX y YYYYYY) que representa los valores RGB (que van desde 000000a FFFFFFinclusive), y un no-cero positivo número entero N, muestran una transición lineal de los N + 2 colores generados a partir de XXXXXX a YYYYYY eso daría como resultado un gradiente de color.

Ejemplo

Entrada

FF3762
F08800
9

Salida

Tenga en cuenta que en nuestro ejemplo, solicité 9 pasos intermedios entre los dos colores, por lo tanto, se mostrarán 11 líneas desde el color inicial hasta el color final.

FF3762
FD3F58
FC474E
FA4F44
F9573A
F75F31
F66727
F46F1D
F37713
F17F09
F08800

Advertencias

Si bien he seguido un proceso lineal simple de derivar los valores enteros para los colores intermedios antes de convertirlos nuevamente en hexadecimales, sus métodos pueden variar. Considere las diversas formas en que uno podría redondear sus números hacia arriba / abajo en consecuencia.

Pruebas

Para hacer esto interesante, proporcioné un fragmento para permitir la prueba de su código, incluido un botón para proporcionarle dos colores aleatorios para probar su código. ¡Mostrar sus resultados es opcional, pero se recomienda!

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) Puede acceder a dos colores aleatorios para su prueba haciendo clic en el botón "Sus dos colores". 2) El número de pasos intermedios será el mismo que el número de caracteres en su nombre de usuario PPCG incluyendo espacios, en el caso de "WallyWest" sería 9 (según mi ejemplo anterior). 3) Ejecute su código con los dos colores y el número y una vez que tenga su lista generada, tiene la opción de pegar su salida en el área de texto y alejarla para obtener el gradiente de color generado.

Mi ejemplo se muestra aquí:

Gradientes

Debo admitir que se ve increíble.

Tenga en cuenta: Como mencioné, mostrar sus pruebas de su salida usando el fragmento es opcional, ¡pero se recomienda! :)

Salida

La salida de la lista debe estar en forma de N + 2 conjuntos de números hexadecimales de 6 dígitos separados por avances de línea (\ n) como se muestra en mi ejemplo anterior. La salida puede ser en forma de líneas separadas, lista separada por espacios / comas, una matriz o lo que sea más adecuado para su idioma ... (Gracias @nimi por los encabezados) Recuerde, si planea probar su código con el fragmento, sin embargo, separe cada "color" depende de usted.

Reglas

Este es el código de golf, por lo que la solución más corta en bytes se coronará como el ganador. No hay escapatorias , naturalmente. La entrada debe aceptar las dos cadenas y un número (que como dije será equivalente al número de letras en su nombre de usuario en PPCG, por lo tanto, su salida resultante siempre tendrá un mínimo de tres líneas de largo.



Anotado y actualizado ... Gracias por el
aviso

Por curiosidad, ¿las aplicaciones de imágenes como Illustrator usan degradados lineales o degradados en algún espacio de color perceptivo? Puedo ver casos de uso para ambos (tal vez estás haciendo la transformación a percepción más adelante, por ejemplo, una textura para un juego).
Robert Fraser

Respuestas:


1

MATL , 31 bytes

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

Esto usa interpolación lineal con redondeo hacia abajo. El formato de entrada es

9
FF3762
F08800

Pruébalo en línea!

Salida gráfica, 31 bytes.

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

Este es el resultado para entradas

5
FF3762
F08800

ingrese la descripción de la imagen aquí

Pruébalo en MATL Online ! El intérprete es actualmente experimental. Si no obtiene ninguna salida, actualice la página y presione "Ejecutar" nuevamente


4

JavaScript (ES6), 130 bytes

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 bytes

Solicita N , luego B eginning-color, luego E nding-color. Necesidades, lo ⎕IO←0cual es predeterminado en muchos sistemas.

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

h[... ]indice en h (que tiene un valor cuando terminamos de evaluar el contenido del paréntesis)

N←⎕solicitud de N numérico (4)

1+agregue uno a N (5)

(... usa eso para dividir el resultado de ...

  ⍞⍞ solicitud de dos cadenas de caracteres ["7E0E7E", "FF3762"]

  (... )∘⍳¨encuentra los índices de los caracteres de cada cadena en ...

   ⎕D,⎕A D igits seguido por A lphabet

   h←asignado a h

  ahora tenemos "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  E B←asignar los índices a E y B [[7,14,0,14,7,14], [15,15,3,7,6,2]]

  -/restar y encerrar B de E [[-8, -1, -3,7,1,12]]

  el resultado hasta ahora es [[-1.6, -0.2, -0.6,1.4,0.2,2.4]]

(... multiplique esto por ...

  2+Ndos más N (6)

   primeros enteros [0,1,2,3,4,5]

 esto nos da [[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∘+¨agregue B a cada [[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], ... ]

redondear hacia abajo [[15,15,3,7,6,2], [13,14,2,8,6,4], [11,14,1,9,6,6], ...]

hacer una lista de listas en la tabla

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

aquí indexamos en 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]]

que es lo mismo que

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

e imprime como

FF3762
DE2864
BE1966
AE1B69
8E0C6B
7E0E7E

degradado

TryAPL en línea!


¡Buen trabajo! ¡La transición se ve genial!
WallyWest

@WallyWest Gracias. Probablemente sea una transición lineal diferente a la mayoría: cada letra se transmite por separado.
Adám

2

Pyth - 35 bytes

Horriblemente golf, simplemente se rindió.

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

Pruébelo en línea aquí .

Ejemplo:

ejemplo


Cuento 11 líneas de gradiente, aunque su nombre PPCG solo tiene 8 letras ... Entonces, ¿no debería haber ingresado 7cb472 93fb8a 8y recibido solo 10 líneas de salida al probar su código?
WallyWest

@WallyWest perdió por completo esa parte en el OP sobre el nombre de usuario, solo usé 9 porque lo hiciste, arreglando.
Maltysen

@WallyWest actualizado
Maltysen

Hola @Maltysen, el gradiente parece un poco extraño ... tienes dos referencias de 93fb8a... ¿Tu código generó dos líneas del mismo valor?
WallyWest

2

PowerShell v2 +, 176 159 150 bytes

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

Toma la entrada como dos cadenas y un número, luego convierte la cadena de inicio en una matriz de cadenas divididas en cada dos caracteres, almacena eso en $x. Luego salimos $acomo nuestra sección de inicio, y hacemos un bucle de ++$na 1(para garantizar una colocación de cerca adecuada).

En cada iteración, se establece $jel número de ayudante en el número actual (que se usa más adelante para garantizar que tengamos el número correcto de pasos entre donde estamos actualmente en nuestro destino) y calcula el siguiente paso en función de un bucle $x.

Cada bucle interno es solo una tarea. Estamos configurando $xen el lugar apropiado igual a una nueva cadena "{0:x2}"usando el -foperador ormat. El x2que aquí se especifica una salida hexadecimal de dos dígitos, y la entrada es la parte derecha del -foperador. PowerShell tiene un operador hexadecimal a decimal nativo 0x, por lo que esta larga expresión anidada por parentesco está utilizando ese operador para convertir el hexadecimal actual en números, restando para encontrar la diferencia que falta (hecho al dividir dinámicamente $baquí como lo hicimos nosotros $a, y usando el módulo para seleccionar el elemento correcto), dividiendo por los $jpasos restantes, convirtiendo en un[int] (PowerShell realiza el redondeo del banco por defecto) y resta ese conteo de pasos del hex actual para obtener lo que nuestro próximo hex debe ser.

El resultado de ese cálculo se almacena de nuevo en $xtres elementos hexadecimales. Eso se encapsula en parens para crear una copia en la tubería y se -joinedita en una sola cadena. Todas esas cadenas resultantes se dejan en la tubería, y la salida a través de lo implícito Write-Outputocurre en la ejecución del programa.


Ejemplo

Me dieron 0ba7c5 y 6c0e50 para mis dos colores, y TimmyD tiene 6 caracteres.

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

Ejemplo de gradiente


1

Python 2, 189 bytes

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)

captura de pantalla de degradado


Magnífico par de colores, @AndrewEpstein ... ¡Buen trabajo con el código!
WallyWest

1

[Groovy] Actualización Final (199 Bytes) - Según solicitud

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

Pruebe la final aquí: https://groovyconsole.appspot.com/script/5130696796405760


ANTIGUAS VERSIONES A CONTINUACIÓN, DECLINADAS POR OP


Groovy (123 bytes)

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

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

Entradas

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

Ejemplo de salida

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

resultados en

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

Pruébelo usted mismo: https://groovyconsole.appspot.com/script/5184465357766656

Con conversiones hexagonales incluidas

Supongo que también estoy haciendo trampa ... Aquí está el script con el uso de hexadecimal:

Nuevo código con conversiones hexadecimales:

​    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 caracteres cuando se juega golf:

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

Salida para 000000 a FFFFFF y 16 (longitud de nombre de usuario)

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

Gradiente monocromático con 1/16 pasos


Err ... ligeramente inválido, la versión original usaba "(0 .. (1.0 / s))", debería haber sido "(1 .. (1.0 / s))".
Urna de pulpo mágico

1
Hola @carusocomputing ... La entrada debe ser dos cadenas hexadecimales y un número entero ... No estoy seguro de si Groovy puede tomar la entrada de esta manera, pero aún no has clavado el resumen ... ¿Podrías actualizar? su código basado en la entrada mencionada en la sección Desafío?
WallyWest

{s-> s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}}('FFFFFF') Resultados en [255,255,255] Puedo agregar 62 bytes a mi código usando esa conversión si realmente quieres que lo haga.
Urna de pulpo mágico

1
Wally, agregué una versión actualizada y subí mi conteo final de bytes a 199 con conversiones incluidas.
Magic Octopus Urn

1

R, 68 bytes

Hay una función incorporada que interpola dos colores:

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

Entrada:

d9e7a5
3ef951
15

Salida: un vector con valores

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

La especificación de color en R requiere un símbolo hash.

Rampa de color

Tracemos algo, como una función:

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)


Gran respuesta, pero el resumen le pide que use todos los pasos que haya en su nombre de usuario PPCG, lo que cuenta el espacio hace 15 ... ¿Podría actualizar su respuesta según FF3762 F08800 15?
WallyWest

@WallyWest Lo siento, me había perdido la parte en la que uno obtiene dos colores y cuenta la longitud de su propio nombre de usuario. ¡Ahora la respuesta debe ser totalmente compatible con la especificación!
Andreï Kostyrka

1

C, 175 169 168 bytes

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

Sin golf:

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

¡Gracias a @ h-walters por reducir 5 bytes!


¿Recordarme qué hace la putssintaxis nuevamente?
WallyWest

Es como printf(), pero no formatea nada, solo imprime la cadena dada tal como está y agrega una nueva línea.
G. Sliepen

Ah, entonces no hay forma de jugar al golf que ... C es un poco restrictivo así, ¿no?
WallyWest

"así que no hay forma de jugar al golf" ... ¡Claro que sí! Pasa puts("")a la tercera parte del primer bucle for ( ;después de convertirse en ,antes) ... +0 bytes. Sin embargo, esto le permite eliminar las llaves después del segundo bucle ... -2 bytes. Puede guardar otro 1 byte eliminando 3 j<3y reemplazándolo con su printfdeclaración (esto es astuto ... printf solo devolverá 2, pero aún tiene que evaluar la tercera vez).
H Walters

... se pueden guardar dos bytes más restando sus valores de retorno sscanf entre sí (lo que resulta en 0), y usando eso en lugar del literal 0en j=0. Una vez que todo esté en su lugar, su programa debería ser 5 bytes más corto y al menos un 50% más extraño.
H Walters

1

sh + ImageMagick, 81 bytes

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

uso:

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

("-depth 8" no es necesario si su IM está compilado con 8bpp como predeterminado)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.