Rainbowlify bir görüntü


23

Bu zorluk, böyle güzel fotoğraflar çekmek için görüntüdeki tonları aşamalı olarak değiştirmekle ilgilidir:

büyük yıldızlı gece ( orijinal )

Meydan okuma

Negatif olmayan iki tamsayı ve seçtiğiniz herhangi bir ortak görüntü dosyası biçiminde bir görüntü alan bir program veya işlev yazın (görüntüye ya da işlenmemiş görüntü verilerine yol alabilirsiniz).

Birinci tamsayı döngüleri , ikinci tamsayı ofseti arayacağız .

Ayrıca kayan nokta adımını , görüntünün alanına bölünen 360 kez çevrimler olarak da tanımlayacağız step = 360 * cycles / (image width * image height).

Görüntüdeki her piksel P için, her seferinde bir satır hareket, soldan sağa, yukarıdan aşağıya (piksellerin harfleri varsa okuma sırasına göre) aşağıdakileri yapın:

  1. Artış renk arasında P ile ofset (gerekirse 0 360 etrafında döngü) derece.

  2. Sonra artışla ofset tarafından adım .

Ortaya çıkan görüntüyü herhangi bir ortak görüntü dosyası biçiminde kaydedin, görüntüleyin veya çıktısını alın.

Bu prosedür, adım adım hale görüntüdeki tüm pikseller tonunu arttıran program aşamasında çevresinde tam döngüler renk gökkuşağı başlangıçta renk dengelenerek başlayarak ofset .

Ne zaman döngüleri 1 ve ofset yukarıdaki Yıldızlı Gece resimde olduğu gibi 0'dır tam renkli bir döngüsü var aralarında, üst ve piksellerin alt satırlar pratikte hiçbir renk kayması ama var.

ayrıntılar

  • Döngüler , negatif olmayan bir tamsayı olabilir, ancak ofsetin 0 ila 359 arasında olduğu varsayılabilir .

  • Ne zaman döngüleri 0'dır görüntüdeki her piksel kendi renk tam olarak kaymış olacak ofset beri adım da 0 olmalıdır. (Bu durumda ofset 0 ise, görüntü hiç değişmez.)

  • Döngüleri ve ofsetin istenirse float olarak girildiğini varsayarsınız (yani 1.0yerine 1). (Tam sayı olmaları gerekmediğinin farkındayım, bu sadece mücadeleyi kolaylaştırıyor.)

  • "Ton", HSL / HSV renk modellerinde ortak olan RGB renk alanı versiyonunu belirtir .

Örnekler

Orijinal:

nehir

Çevrimler = 1, ofset = 0:

nehir çıkışı 1

Çevrimler = 1, ofset = 180:

nehir çıkışı 2

Orijinal:

küreleri

Çevrimler = 2, ofset = 60:

küre çıkışı

Orijinal:

gün batımı
(Teşekkürler ArtOfCode .)

Çevrimler = 1, ofset = 120:

gün batımı çıkışı

Orijinal:

kapı tokmağı
(Teşekkürler Doorknob .)

Çevrimler = 1, ofset = 0:

kapı tokmağı çıkışı 1

Çevrimler = 4, ofset = 0:

kapı tokmağı çıkışı 2

Çevrimler = 200, ofset = 0:

kapı tokmağı çıkışı 3

Çevrimler = 30000, ofset = 0:

kapı tokmağı çıkışı 4

(Bu görüntüler, sıkıştırdıkları sıkıştırmadan dolayı mükemmel pikseller olmayabilir.)

puanlama

Bayt cinsinden en kısa kod kazanır. Tiebreaker daha yüksek oyla cevap verdi.

Kendi harika görünen test resimlerini yayınlayan cevaplar benden daha fazla brownie puanı alacak.


6
Görünüşe göre Doorknob biraz ot içiyor.
Denker

Bir tam sayı dizisini, dönüş değeri "veya çıktı ham" olarak ekleneceği için tahmin ediyorum?
Marv

2
@Marv Hayır. Görüntünün ham baytları (seçtiğiniz ortak biçimde, ppm demek ) doğrudan stdout'a yönlendirilebilir.
Calvin'in Hobileri

2
Çıktılar örneklerinizle aynı mı olmalı? Biraz farklı görüntüler alıyorum .
DJMcMayhem

1
@DrGreenEggsandHamDJ Görsel olarak bir fark söyleyemiyorsanız, o zaman sorun değil. Piksel mükemmellik gerekli değildir (imgur yine de resimlerimi zararsız bir şekilde sıkıştırmış olabilir).
Calvin'in Hobileri

Yanıtlar:


8

Pyth, 86 bayt, tam program

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

Pyth, renk alanı içinde yerleşik dönüşümler yapmaz - bu gerçek bir anlaşma.

Stdin'de aşağıdaki biçimde girdi alır:

input_filename.png
offset
cycles

Çıktı görüntüsü şuna yazılır o.png.


Bu, renkli küpü köşegen çevresinde döndürerek ve daha sonra aralığın dışındaki herhangi bir değeri sıkarak çalışır.

Eğer atarafından döndürülmesi açısıdır ve r, g, bgiriş rengidir, yeni bir renk hesaplamak r', g', b'tarafından:

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

Python, 379 bayt

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

Bu bir .jpgas girişi için bir yol alır . Değiştirebileceğiniz rağmen, png ile çalışmaz r,g,b=i.split();için r,g,b=i.split()[:3];bir png resim yüklemek için.

İşte bazı resimler:

Orijinal:

görüntü tanımını buraya girin

Ofset: 0, Çevrimler: 4

görüntü tanımını buraya girin

Orijinal:

görüntü tanımını buraya girin

Ofset 0, 1 döngü:

görüntü tanımını buraya girin

Orijinal:

görüntü tanımını buraya girin

Ofset 0, 2.5 döngü:

görüntü tanımını buraya girin


6

Java (Tam program), 491 488 bayt (Thanks @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);}}

Ungolfed

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

açıklama

  • Kullanımı: Oldukça basit. İle derleyin java -c Q.java. İle koş java Q <cycles> <offset> <imagepath>. Mevcut görüntüyü geçersiz kılacaktır, bu yüzden dikkatli olun.

  • İlk başta sadece bir çözüm yapacaktım ama bunlar üzerinden yapılan ithalatlarla nasıl başa çıkacağımı bilemedim, bu yüzden tam gideceğimi düşündüm , bu muhtemelen yine de kazanamayacaktı.

Sonuçlar:

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

görüntü tanımını buraya girin


1
Gelecekte başvurmak için, yalnızca yöntemle yaptığınız yanıtlarla, normalde yaptığınız gibi aynı işlemleri yapabilirsiniz. Onları yöntem gövdesinin dışına koy ve baytları say. Ayrıca, bazı durumlarda birkaç bayttan tasarruf etmek için yalnızca bir kez ihtiyaç duyacak olursanız, sınıfları içe aktarmak yerine tam olarak niteleyebilirsiniz.
Geobits

Ayrıca, içe aktardığınız bir neden yoktur java.io.Fileyerine java.io.*?
Geobits

Teşekkürler, bilmek güzel. İkincisi, hayır, sebep yok. İyi bir nokta.
Marv

Neden import ** static**, sadece değil import?
Solomon Ucko

1
Böylece arayabilirim ImageIO::readve hazırlamak ImageIO::writezorunda kalmadan ImageIO.: Bu 9 bayt ( static .*) ekler ancak 16 ( ImageIO.iki kez) kazandırır .
Marv
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.