Генерація градієнтів RGB


18

Змагання

З урахуванням двох заголовних шістнадцятиричні рядки (довгі обидва 6 символів, XXXXXX і YYYYYY) , що представляє значення RGB ( в діапазоні від 000000до FFFFFFвключно), а позитивний ненульовий число N, відображати лінійний перехід з N + 2 кольорів , отриманих від XXXXXX до YYYYYY це призведе до кольорового градієнта.

Приклад

Вхідні дані

FF3762
F08800
9

Вихід

Зверніть увагу, у нашому прикладі я просив 9 проміжних кроків між двома кольорами, тому 11 рядків буде відображено від початкового кольору до кінцевого кольору

FF3762
FD3F58
FC474E
FA4F44
F9573A
F75F31
F66727
F46F1D
F37713
F17F09
F08800

Коваджі

Хоча я пішов з простим лінійним процесом отримання цілих значень проміжних кольорів, перш ніж перетворити їх назад у шістнадцятковий, ваші методи можуть відрізнятися. Будь ласка, врахуйте різні способи відповідного округлення / зменшення номерів .

Тестування

Щоб зробити це цікавим, я надав фрагмент, щоб дозволити тестування вашого коду, включно з кнопкою, щоб надати вам два випадкових кольори для перевірки вашого коду. Відображення результатів необов’язково, але рекомендується!

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) Ви можете отримати доступ до двох випадкових кольорів для свого тесту, натиснувши кнопку "Ваші два кольори". 2) Кількість проміжних кроків буде такою ж, як кількість символів у вашому імені користувача PPCG, включаючи пробіли, у випадку "WallyWest" це буде 9 (як у моєму прикладі вище). 3) Запустіть свій код двома кольорами та цифрою, і як тільки у вас буде створений список, ви зможете вставити свій результат у текстову область та вкладку подалі від неї, щоб отримати створений градієнт кольору.

Мій приклад показаний тут:

Градієнти

Треба визнати, це виглядає досить приголомшливо!

Зверніть увагу: Як я вже згадував, показ тестування вашого результату за допомогою фрагмента необов’язковий, але рекомендується! :)

Вихід

Вихід списку має бути у вигляді N + 2 наборів шестизначних шестизначних чисел, розділених каналами рядків (\ n), як показано в моєму прикладі вище. Вихід може бути у вигляді окремих рядків, списку, розділеного пробілом / комами, масиву або будь-якого іншого, що найкраще підходить для вашої мови ... (Спасибі @nimi за голову вгору) Будь ласка, пам’ятайте, що якщо ви плануєте тестувати свій код із фрагмент, проте кожен окремий "колір" залежить від вас.

Правила

Це код-гольф, тому найкоротше рішення в байтах буде короновано переможця. Без лазівки , природно. Вхід повинен приймати два рядки та число (які, як я вже сказав, будуть еквівалентні кількості букв у вашому імені користувача на PPCG, таким чином, отриманий результат завжди буде мінімум трьома рядками.



Помічено та оновлено ... Дякую за голову вгору (+1)
WallyWest

Чи не цікаво, чи додатки із зображеннями, як Illustrator, використовують лінійні градієнти чи градієнти у певному кольоровому просторі? Я бачу випадки використання для обох (можливо, ви робите перетворення на перцептивне пізніше, наприклад, текстуру для гри).
Роберт Фрейзер

Відповіді:


1

MATL , 31 байт

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

Для цього використовується лінійна інтерполяція з округленням вниз. Формат вводу є

9
FF3762
F08800

Спробуйте в Інтернеті!

Графічний вихід, 31 байт

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

Це результат для входів

5
FF3762
F08800

enter image description here

Спробуйте в MATL Online ! На даний момент перекладач експериментальний. Якщо ви не отримаєте жодного результату, оновіть сторінку та натисніть "Виконати" ще раз.


4

JavaScript (ES6), 130 байт

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

Діалог APL , 44 байти

Підказки для N , потім B eginning color, потім E nding-color. Потреби, ⎕IO←0які за замовчуванням застосовуються у багатьох системах.

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

h[... ]індекс в h (що має значення, коли ми закінчуємо оцінку вмісту дужки)

N←⎕підказка для числового N (4)

1+додати його до N (5)

(... використовуйте це для поділу результату ...

  ⍞⍞ підказка для двох символьних рядків ["7E0E7E", "FF3762"]

  (... )∘⍳¨знайти індекси символів кожного рядка в ...

   ⎕D,⎕A D запалює, а потім A lphabet

   h←призначений h

  тепер у нас є "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  E B←присвоїти індекси E і B [[7,14,0,14,7,14], [15,15,3,7,6,2]]

  -/відняти і скласти B від E [[-8, -1, -3,7,1,12]]

  поки що результат [[-1.6, -0.2, -0.6,1.4.0.2,2.4]]

(... помножте це на ...

  2+N два плюс N (6)

   перші цілі числа [0,1,2,3,4,5]

 це дає нам [[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∘+¨додати В до кожного [[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], ... ]

закруглюйте [[15,15,3,7,6,2], [13,14,2,8,6,4], [11,14,1,9,6,6], ...]

скласти список списків у таблицю

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

тут ми індексуємо на h , даючи

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

що те саме

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

і друкує як

FF3762
DE2864
BE1966
AE1B69
8E0C6B
7E0E7E

градієнт

СпробуйтеAPL онлайн!


Хороша робота! Перехід виглядає чудово!
WallyWest

@WallyWest Дякую Це, мабуть, інший лінійний перехід, ніж більшість з них: Кожна літера переходить окремо.
Адам

2

Pyth - 35 байт

Жахливо гольфували, просто здалися.

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

Спробуйте його онлайн тут .

Приклад:

приклад


Я рахую 11 рядків градієнта, хоча у вашому імені PPCG є лише 8 літер ... Тож чи не слід було ви вводити 7cb472 93fb8a 8і отримували лише 10 рядків виводу при тестуванні свого коду?
WallyWest

@WallyWest повністю пропустив цю частину в ОП щодо імені користувача, я просто використав 9 зусиль, які ви зробили, виправляючи.
Малтісен

@WallyWest оновлено
Maltysen

Привіт @Maltysen, градієнт здається трохи дивним ... у вас є дві посилання на 93fb8a... Чи виводив ваш код два рядки однакового значення?
WallyWest

2

PowerShell v2 +, 176 159 150 байт

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

Приймає вхід як два рядки і число, а потім перетворює початковий рядок у масив рядків, розділених на кожні два символи, і зберігає їх у $x. Потім ми виводимо $aяк наш стартовий розділ, і петлю від ++$nдо 1(щоб забезпечити належне огорожу).

Кожна ітерація встановлює помічник $jпоточного номера (використовується пізніше, щоб переконатися, що ми отримали потрібну кількість кроків між тим, де ми зараз перебуваємо до нашого пункту призначення) та обчислює наступний крок на основі циклу через$x .

Кожна внутрішня петля - це лише завдання. Ми встановлюємо $xвідповідне місце, рівне новій рядку "{0:x2}"за допомогою -fоператора ormat. x2Тут задає висновок шістнадцятирічного двозначного, а вхід правого боку -fоператора. PowerShell має власний шістнадцятковий десятковий оператор 0x, тому цей тривалий вираз, вкладений пароном, використовує цей оператор для перетворення поточного шістнадцяткового числа в числа, віднімання, щоб знайти різницю, яка ще повинна пройти (робиться шляхом динамічного розбиття $bтут, як ми це робили $a, і використовуючи модуль для вибору потрібного елемента), поділяючи на $jкроки, що залишилися, передаваючи на[int] (За замовчуванням PowerShell робить банкрутство банкіра) і віднімає цей підрахунок кроків від поточного шестигранника, щоб отримати те, що має бути наступним шестигранником.

Результат цього обчислення зберігається назад у $xвигляді трьох шестигранних елементів. Це інкапсульовано в паренах, щоб створити копію на конвеєрі, і -joinразом об'єднати в єдиний рядок. Усі ці результуючі рядки залишаються на конвеєрі, а виведення за допомогою неявних Write-Outputвідбувається при виконанні програми.


Приклад

Мені дали 2ba7c5 та 6c0e50 за два мої кольори, а TimmyD має 6 символів.

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

Приклад градієнта


1

Пітон 2, 189 байт

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)

скріншот градієнта


Чудова пара кольорів, @AndrewEpstein ... Приємна робота з кодом!
WallyWest

1

[Groovy] Остаточне оновлення (199 байт) - Відповідно до запиту

Не гольф

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

Гольф

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

Спробуйте фінал тут: https://groovyconsole.appspot.com/script/5130696796405760


СТАРІ ВЕРСІЇ НИЖЕ, ВИЗНАЧЕНІ ОП


Groovy (123 байт)

Гольф

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

Не гольф

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

Вхідні дані

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

Приклад виводу

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

призводить до

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

Спробуйте самі: https://groovyconsole.appspot.com/script/5184465357766656

З включеними шестигранними перетвореннями

Здогадуюсь, я теж обманюю ... Ось сценарій із використанням шістнадцяткових:

Новий код із шістнадцятковою конверсією:

​    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 символів при гольфі:

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

Вихід для 000000 до FFFFFF та 16 (Довжина користувача)

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

Монохроматичний градієнт з 1/16 кроків


Помилка ... трохи недійсна, використана оригінальна версія "(0 .. (1.0 / s))", повинна була бути "(1 .. (1.0 / s))".
Чарівна урва восьминога

1
Привіт @carusocomputing ... Вхід повинен бути двома шістнадцятковими рядками і цілим числом ... Я не впевнений, чи Groovy може взяти такий вклад, але ви не зовсім прибили цвіт ... Чи можете ви оновити Ваш код на основі входу, згаданого в розділі «Виклик»?
WallyWest

{s-> s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}}('FFFFFF') Результати в [255,255,255] Я можу додати 62 байти до свого коду, використовуючи цю конверсію, якщо ви цього дуже хочете.
Magic Octopus Urn

1
Wally, я додав оновлену версію і збільшив остаточну кількість байтів до 199 із включеними перетвореннями.
Magic Octopus Urn

1

R, 68 байт

Існує вбудована функція, яка інтерполює два кольори:

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

Вхід:

d9e7a5
3ef951
15

Вихід: вектор зі значеннями

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

Специфікація кольору в R вимагає хеш-символу.

Колірний пандус

Давайте побудуємо щось на зразок функції:

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)


Чудова відповідь, але в короткому запиті пропонується використати стільки кроків, скільки є у вашому імені користувача PPCG, підрахунок місця якого становить 15 ... Чи можете ви, будь ласка, оновити свою відповідь на основі FF3762 F08800 15?
WallyWest

@WallyWest Вибачте, я пропустив ту частину, де один отримує два кольори і рахує свою власну довжину імені користувача. Тепер відповідь повинна повністю відповідати специфікації!
Андрей Костирка

1

C, 175 169 168 байт

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

Безголівки:

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

Дякуємо @ h-walters за бриття 5 байт!


Нагадайте, що putsзнову робить синтаксис?
WallyWest

Це як printf(), але не робить форматування, натомість він просто друкує заданий рядок таким, яким він є, і додає новий рядок.
Г. Сліпен

А, значить, немає ніякого способу гри в гольф, який ... С такий обмежувальний, чи не так?
WallyWest

"так що не існує жодного способу гри в гольф" ... Звичайно, є! Перейдіть puts("")до третьої частини першої для циклу ( ;після того, як ставали ,раніше) ... +0 байт. Однак це дозволяє зняти фігурні дужки після другого циклу ... -2 байти. Ви можете зберегти ще один байт, видаливши з нього 3 j<3та замінивши його своїм printfвисловлюванням (це підступно ... printf поверне лише 2, але це все одно має бути оцінено втретє).
H Walters

... ще два байти можна зберегти, віднімаючи повернені значення sscanf один від одного (в результаті чого 0), і використовуючи це замість буквального 0в j=0. Як тільки тут все на місці, ваша програма повинна бути на 5 байт коротшою і принаймні на 50% незнайомою.
H Walters

1

sh + ImageMagick, 81 байт

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

використання:

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

("-depth 8" не потрібен, якщо ваш чат компілюється з 8bpp за замовчуванням)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.