Rainbowlify An Image

23

Tantangan ini adalah tentang secara bertahap mengubah rona dalam gambar untuk membuat gambar yang cantik seperti ini:

Malam Berbintang besar ( asli )

Tantangan

Tulis program atau fungsi yang menggunakan dua bilangan bulat non-negatif dan gambar dalam format file gambar umum apa pun yang Anda pilih (Anda dapat mengambil jalur ke gambar atau data gambar mentah).

Kami akan memanggil integer pertama siklus dan integer kedua offset .

Kami juga akan menetapkan langkah titik mengambang sebagai 360 kali siklus dibagi dengan luas gambar, atau step = 360 * cycles / (image width * image height).

Untuk setiap piksel P dalam gambar, memindahkan satu baris sekaligus, kiri-ke-kanan, atas-ke-bawah (yaitu dalam urutan pembacaan jika pikselnya berupa huruf), lakukan hal berikut:

  1. Meningkatkan rona dari P oleh diimbangi derajat (perulangan sekitar 360-0 jika perlu).

  2. Kemudian tingkatkan offset dengan langkah .

Simpan, tampilkan, atau hasilkan gambar mentah yang dihasilkan dalam format file gambar apa pun yang umum.

Prosedur ini secara bertahap meningkatkan rona dari semua piksel dalam gambar, membuat putaran lingkaran penuh di sekitar pelangi rona , mulai dengan awalnya mengimbangi rona dengan offset .

Ketika siklus 1 dan offset adalah 0, seperti pada gambar Starry Night di atas, baris atas dan bawah piksel praktis tidak memiliki pergeseran rona tetapi di antaranya ada siklus warna penuh.

Detail

  • Siklus dapat berupa bilangan bulat non-negatif, tetapi Anda dapat menganggap bahwa offset dari 0 hingga 359 inklusif.

  • Ketika siklus adalah 0, setiap pixel dalam gambar akan memiliki rona bergeser persis diimbangi sejak langkah harus 0 juga. (Dalam hal ini jika offset adalah 0 maka gambar tidak berubah sama sekali.)

  • Anda dapat menganggap siklus dan offset adalah input mengapung jika diinginkan (yaitu, 1.0bukan 1). (Saya menyadari mereka tidak perlu bilangan bulat sama sekali, itu hanya membuat tantangan lebih sederhana.)

  • "Hue" mengacu pada versi ruang warna RGB, umum dalam model warna HSL / HSV .

Contohnya

Asli:

sungai

Siklus = 1, offset = 0:

keluaran sungai 1

Siklus = 1, offset = 180:

keluaran sungai 2

Asli:

bola

Siklus = 2, offset = 60:

output bidang

Asli:

matahari terbenam
(Terima kasih ArtOfCode .)

Siklus = 1, offset = 120:

output matahari terbenam

Asli:

gagang pintu
(Terima kasih Doorknob .)

Siklus = 1, offset = 0:

Output gagang pintu 1

Siklus = 4, offset = 0:

Output gagang pintu 2

Siklus = 200, offset = 0:

Output gagang pintu 3

Siklus = 30000, offset = 0:

Output gagang pintu 4

(Gambar-gambar ini mungkin bukan piksel yang sempurna karena imgur mengompresnya.)

Mencetak gol

Kode terpendek dalam byte menang. Tiebreaker adalah jawaban dengan suara lebih tinggi.

Jawaban yang memposting gambar tes keren mereka sendiri akan mendapatkan poin lebih banyak dari saya.

Hobi Calvin
sumber
6
Sepertinya Doorknob sedang merokok.
Denker
Saya menganggap array bilangan bulat karena nilai pengembalian akan dimasukkan dalam "atau output mentah"?
Marv
2
@ Marv Tidak. Maksud saya byte mentah dari gambar (dalam format umum yang Anda pilih, katakan ppm ) dapat disalurkan langsung ke stdout.
Calvin Hobbies
2
Apakah output harus identik dengan contoh Anda? Saya mendapatkan gambar yang sedikit berbeda.
DJMcMayhem
1
@DrGreenEggsandHamDJ Jika Anda tidak bisa membedakan secara visual maka mungkin tidak apa-apa. Pixel perfection tidak diperlukan (bagaimanapun imgur mungkin telah mengkompres gambar saya).
Calvin Hobbies

Jawaban:

8

Pyth, 86 byte, program lengkap

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

Pyth tidak memiliki konversi ruang warna bawaan - ini adalah real deal.

Mengambil input dalam format berikut di stdin:

input_filename.png
offset
cycles

Gambar output ditulis untuk o.png.


Ini berfungsi dengan memutar kubus warna di sekitar diagonal, dan kemudian menjepit nilai apa pun di luar rentang.

Jika asudut untuk dirotasi, dan r, g, bmerupakan warna input, kami menghitung warna baru r', g', b'dengan:

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])
orlp
sumber
6

Python, 379 byte

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

Ini mengambil jalur ke .jpginput sebagai. Ini tidak akan berfungsi dengan png, meskipun Anda dapat mengubah r,g,b=i.split();ke r,g,b=i.split()[:3];untuk memuat gambar png.

Berikut ini beberapa gambar:

Asli:

masukkan deskripsi gambar di sini

Offset: 0, Siklus: 4

masukkan deskripsi gambar di sini

Asli:

masukkan deskripsi gambar di sini

Offset 0, 1 siklus:

masukkan deskripsi gambar di sini

Asli:

masukkan deskripsi gambar di sini

Offset 0, 2,5 siklus:

masukkan deskripsi gambar di sini

DJMcMayhem
sumber
6

Java (Program lengkap), 491 488 bytes (Terima kasih @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);}}

Tidak disatukan

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

Penjelasan

  • Penggunaan: Cukup mudah. Kompilasi dengan java -c Q.java. Jalankan dengan java Q <cycles> <offset> <imagepath>. Akan menimpa gambar yang ada, jadi berhati-hatilah.

  • Saya akan membuat solusi metode saja pada awalnya tetapi saya tidak tahu bagaimana menangani impor pada mereka, jadi saya pikir saya akan menjadi penuh , ini mungkin tidak akan menang lagi: ^)

Hasil:

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

masukkan deskripsi gambar di sini

Marv
sumber
1
Untuk referensi di masa mendatang, Anda dapat melakukan impor untuk jawaban metode saja sama seperti yang biasa Anda lakukan. Letakkan saja di luar body metode dan hitung byte. Anda juga dapat sepenuhnya memenuhi syarat kelas daripada mengimpornya jika Anda hanya akan membutuhkannya sekali, untuk menyimpan beberapa byte dalam beberapa kasus.
Geobits
Juga, apakah ada alasan Anda mengimpor java.io.Filebukan java.io.*?
Geobits
Terima kasih, senang tahu. Dan kedua, tidak, tidak ada alasan. Poin bagus.
Marv
Kenapa import ** static**, bukan adil import?
Solomon Ucko
1
Sehingga saya dapat memanggil ImageIO::readdan ImageIO::writetanpa harus menambahkan ImageIO.: Ini menambah 9 byte ( static .*) tetapi menyimpan 16 ( ImageIO.dua kali).
Marv