Rainbowlify зображення


23

Ця задача полягає в тому, щоб поступово зміщувати відтінки в зображенні, щоб зробити такі гарні зображення:

велика зоряна ніч ( оригінал )

Виклик

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

Ми будемо називати перше ціле число циклами, а друге ціле число - зміщенням .

Ми також визначимо крок з плаваючою комою у 360 разів циклів, розділених на площу зображення, абоstep = 360 * cycles / (image width * image height) .

Для кожного пікселя P на зображенні, переміщуючи по одному рядку, вліво-вправо, вгору-вниз (тобто в порядку читання, якщо пікселі були літерами), виконайте наступне:

  1. Збільшення колірного тону від Р по офсетним градусам (цикл навколо від 360 до 0 , якщо це необхідно).

  2. Потім збільшуйте зміщення за кроком .

Збережіть, відображте або виведіть вихідне зображення в будь-якому загальному форматі файлу зображень.

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

Якщо цикл дорівнює 1, а зміщення дорівнює 0, як на зображенні Зоряної ночі вгорі, верхній і нижній рядки пікселів практично не змінюють відтінку, але між ними є повний кольоровий цикл.

Деталі

  • Цикли можуть бути будь-якими цілими негативними числами, але можна припустити, що зміщення становить від 0 до 359 включно.

  • Якщо циклів дорівнює 0, кожен піксель зображення буде зміщений на точно зміщений, оскільки крок також повинен бути 0. (У цьому випадку, якщо зміщення дорівнює 0, зображення взагалі не змінюється.)

  • Ви можете припустити, що цикли та зміщення при бажанні вводяться як поплавці (тобто 1.0замість 1). (Я розумію, що вони взагалі не повинні бути цілими числами, це просто робить виклик більш простим.)

  • "Відтінок" означає версію кольорового простору RGB, поширену в кольорових моделях HSL / HSV .

Приклади

Оригінал:

річка

Цикли = 1, зміщення = 0:

річка вихід 1

Цикли = 1, зміщення = 180:

річка 2

Оригінал:

сфери

Цикли = 2, зміщення = 60:

вихід сфери

Оригінал:

захід сонця
(Спасибі ArtOfCode .)

Цикли = 1, зміщення = 120:

вихід на захід сонця

Оригінал:

дверна ручка
(Дякую Дорнобі .)

Цикли = 1, зміщення = 0:

вихід дверної ручки 1

Цикли = 4, зміщення = 0:

вихід двері 2

Цикли = 200, зміщення = 0:

вихід дверної ручки 3

Цикли = 30000, зміщення = 0:

вихід дверної ручки 4

(Ці зображення можуть не бути ідеальними для пікселів через їх стиснення.)

Оцінка балів

Виграє найкоротший код у байтах. Tiereaker є вищою відповіді.

Відповіді, які розміщують свої власні цікаві тестові зображення, отримають від мене більше очок брауні.


6
Це схоже на те, що Дорнобаб курить якийсь горщик.
Денкер

Я припускаю масив цілих чисел, оскільки значення, що повертається, буде включено до "або вихідного сировини"?
Марв

2
@ Марв. Ні. Я маю на увазі необроблені байти зображення (у вибраному вами загальному форматі, скажімо, у ppm ), можна прокласти прямо на stdout.
Захоплення Кальвіна

2
Чи повинні виходи бути ідентичними вашим прикладам? Я отримую трохи інші зображення.
DJMcMayhem

1
@DrGreenEggsandHamDJ Якщо ви не можете візуально сказати різницю, то, мабуть, це добре. Вдосконалення пікселів не потрібно (imgur все одно може втратити мої зображення).
Хобі Кальвіна

Відповіді:


8

Pyth, 86 байт, повна програма

=N.tE7=Z*6*.n0cEl.n'zMmhtS[0255ss*VG.>+Lc-1.tH1 3[.tH1Kc.tH0@3 2_K)d)3.wmmgk~-NZd'z

Pyth не має вбудованого перетворення кольорового простору - це справжня справа.

Здійснює введення в stdin у наступному форматі:

input_filename.png
offset
cycles

Вихідне зображення записується в o.png.


Це працює, обертаючи кольоровий куб навколо його діагоналі, а потім затискаючи будь-які значення за межами діапазону.

Якщо aкут обертання на і r, g, bє кольором введення, ми обчислюємо новий колір r', g', b'за:

o = cos(a), i = sin(a) / sqrt(3)
n = (1 - o) / 3
m = [n + o, n - i, n + i]
clamp(c) = max(0, min(255, c))
r' = clamp(r*m[0] + g*m[1] + b*m[2])
g' = clamp(r*m[2] + g*m[0] + b*m[1])
b' = clamp(r*m[1] + g*m[2] + b*m[0])

6

Пітон, 379 байт

from PIL.Image import*
from colorsys import*
def f(H,c,I):
 i=open(I);x,y=i.size;S=1.*c/(x*y);r,g,b=i.split();R=[];G=[];B=[]
 for x,y,z in zip(r.getdata(),g.getdata(),b.getdata()):
  e=255.;h,s,v=rgb_to_hsv(x/e,y/e,z/e);t=hsv_to_rgb(h+H,s,v);H=H+S%1.;x,y,z=[int(x*e)for x in t];R.append(x);G.append(y);B.append(z)
 p=Image.putdata;p(r,R);p(g,G);p(b,B);return merge('RGB',(r,g,b))

Це бере шлях до .jpgвхідного коду. Він не буде працювати з PNG, хоча ви можете змінити r,g,b=i.split();доr,g,b=i.split()[:3]; завантажити зображення PNG.

Ось кілька зображень:

Оригінал:

введіть тут опис зображення

Зсув: 0, Цикли: 4

введіть тут опис зображення

Оригінал:

введіть тут опис зображення

Зсув 0, 1 цикл:

введіть тут опис зображення

Оригінал:

введіть тут опис зображення

Зсув 0, 2,5 циклів:

введіть тут опис зображення


6

Java (повна програма), 491 488 байт (спасибі @Geobits)

import java.awt.*;import java.io.*;import static javax.imageio.ImageIO.*;class Q{public static void main(String[]v)throws Exception{File f=new File(v[2]);java.awt.image.BufferedImage b=read(f);for(int i=0,j,h=b.getHeight(),w=b.getWidth();i<h;i++)for(j=0;j<w;){Color c=new Color(b.getRGB(j,i));float[]a=new float[3];c.RGBtoHSB(c.getRed(),c.getGreen(),c.getBlue(),a);b.setRGB(j++,i,c.HSBtoRGB((a[0]+Float.valueOf(v[1])/360+(i*w+j)*Float.valueOf(v[0])/w/h)%1,a[1],a[2]));}write(b,"png",f);}}

Безумовно

import java.awt.*;
import java.io.*;

import static javax.imageio.ImageIO.*;

class A79200 {
    public static void main(String[] v) throws Exception {
        File file = new File(v[2]);
        java.awt.image.BufferedImage image = read(file);
        for (int i = 0, j, height = image.getHeight(), width = image.getWidth(); i < height; i++)
            for (j = 0; j < width; ) {
                Color color = new Color(image.getRGB(j, i));
                float[] arr = new float[3];
                color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), arr);
                image.setRGB(j++, i, color.HSBtoRGB((arr[0] + Float.valueOf(v[1]) / 360 + (i * width + j) * Float.valueOf(v[0]) / width / height) % 1, arr[1], arr[2]));
            }
        write(image, "png", file);
    }
}

Пояснення

  • Використання: досить прямо. Компілювати з java -c Q.java. Бігайте з java Q <cycles> <offset> <imagepath>. Буде замінено існуючий образ, тому будьте уважні.

  • Спочатку я збирався прийняти рішення лише для методу, але я не зовсім знав, як впоратись з імпортом, тому я подумав, що пітиму на повну , мабуть, все одно не виграю: ^)

Результати:

Image 1: 1 cycle, 0 offset

1

Image 1: 1 cycle, 180 offset

2

Image 2: 2 cycles, 60 offset

3

Image 3: 1 cycle, 120 offset

4

Image 4: 1 cycle, 0 offset

5

Image 4: 4 cycles, 0 offset

6

Image 4: 200 cycles, 0 offset

7

Bonus: The Starry Night, 1 cycle, 0 offset

введіть тут опис зображення


1
Для подальшого ознайомлення, ви можете робити імпорт для відповідей лише методів так само, як і зазвичай. Просто поставте їх поза тілом методу і порахуйте байти. Ви також можете повністю кваліфікувати класи, а не імпортувати їх, якщо вам знадобиться лише один раз, щоб зберегти кілька байтів у деяких випадках.
Геобіт

Також є причина, яку ви імпортуєте java.io.Fileзамість java.io.*?
Геобіт

Дякую, добре знати. А по-друге, ні, немає причини. Влучне зауваження.
Марв

Чому import ** static**, а не просто import?
Соломон Учко

1
Так що я можу зателефонувати ImageIO::readі ImageIO::writeбез попередньої оплати ImageIO.: Це додає 9 байт ( static .*), але економить 16 ( ImageIO.двічі).
Марв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.