Rainbowlify รูปภาพ


23

ความท้าทายนี้เกี่ยวกับการเปลี่ยนเฉดสีในรูปภาพเพื่อให้ภาพสวยเช่นนี้:

ใหญ่ Starry Night ( ต้นฉบับ )

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้จำนวนเต็มสองจำนวนที่ไม่เป็นลบและรูปภาพในรูปแบบไฟล์ภาพทั่วไปที่คุณเลือก (คุณสามารถพา ธ ไปยังภาพหรือข้อมูลภาพดิบ)

เราจะเรียกคนแรกจำนวนเต็มรอบและครั้งที่สองจำนวนเต็มชดเชย

นอกจากนี้เราจะกำหนดจุดลอยตัวขั้นตอนเป็น 360 ครั้งรอบstep = 360 * cycles / (image width * image height)แบ่งตามพื้นที่ของภาพหรือ

สำหรับแต่ละพิกเซลPในภาพให้ย้ายทีละครั้งจากซ้ายไปขวาจากบนลงล่าง (เช่นในลำดับการอ่านถ้าพิกเซลเป็นตัวอักษร) ให้ทำดังนี้:

  1. เพิ่มเฉดสีของPด้วยองศาชดเชย (วนรอบจาก 360 เป็น 0 หากจำเป็น)

  2. จากนั้นเพิ่มขึ้นชดเชยโดยขั้นตอน

บันทึกแสดงผลหรือส่งออกภาพที่เกิดขึ้นในรูปแบบไฟล์ภาพทั่วไป

ขั้นตอนนี้จะเพิ่มขึ้นเพิ่มสีของพิกเซลทั้งหมดในภาพที่ทำให้รอบลูปเต็มรอบรุ้งสีเริ่มต้นโดยการเริ่มชดเชยสีโดยการชดเชย

เมื่อรอบเป็น 1 และออฟเซ็ตเป็น 0 เช่นเดียวกับในภาพ Starry Night ข้างบนแถวพิกเซลด้านบนและด้านล่างไม่มีการเปลี่ยนสี แต่ในระหว่างนั้นจะมีวงจรสีเต็มรูปแบบ

รายละเอียด

  • รอบสามารถเป็นจำนวนเต็มใด ๆ ที่ไม่เป็นลบได้ แต่คุณอาจคิดว่าออฟเซ็ตนั้นมีค่าตั้งแต่ 0 ถึง 359

  • เมื่อวงรอบเป็น 0 ทุกพิกเซลในภาพจะถูกเปลี่ยนสีโดยการชดเชยอย่างถูกต้องตั้งแต่ขั้นตอนต้องเป็น 0 เช่นกัน (ในกรณีนี้ถ้าชดเชยเป็น 0 ภาพจะไม่เปลี่ยนแปลงเลย)

  • คุณอาจจะสมมติรอบและชดเชยมีการป้อนข้อมูลเป็นลอยถ้าต้องการ (เช่น1.0แทน1) (ฉันรู้ว่าพวกเขาไม่จำเป็นต้องเป็นจำนวนเต็มเลยมันทำให้การท้าทายง่ายขึ้น)

  • "เว้" หมายถึงรุ่นพื้นที่สี RGB ทั่วไปในHSL / HSV รูปแบบสี

ตัวอย่าง

เดิม:

แม่น้ำ

รอบ = 1, ชดเชย = 0:

แม่น้ำที่ไหลออก 1

รอบ = 1, ชดเชย = 180:

แม่น้ำที่ไหลออก 2

เดิม:

ทรงกลม

รอบ = 2, ชดเชย = 60:

เอาท์พุททรงกลม

เดิม:

พระอาทิตย์ตกดิน
(ขอบคุณArtOfCode )

รอบ = 1, ชดเชย = 120:

พระอาทิตย์ตกออก

เดิม:

ลูกบิดประตู
(ขอบคุณDoorknob )

รอบ = 1, ชดเชย = 0:

ลูกบิดประตูออก 1

รอบ = 4, ชดเชย = 0:

ลูกบิดประตูเอาท์พุท 2

รอบ = 200, ชดเชย = 0:

ลูกบิดประตูเอาท์พุท 3

รอบ = 30000, ชดเชย = 0:

ลูกบิดประตูเอาท์พุท 4

(รูปภาพเหล่านี้อาจไม่ได้เป็นพิกเซลที่สมบูรณ์แบบเนื่องจาก imgur บีบอัดภาพ)

เกณฑ์การให้คะแนน

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ Tiebreaker เป็นคำตอบที่โหวตให้สูงกว่า

คำตอบที่โพสต์ภาพทดสอบที่ดูเท่ห์ของตัวเองจะได้รับคะแนนบราวนี่มากขึ้นจากฉัน


6
ดูเหมือนว่า Doorknob กำลังสูบบุหรี่อยู่
Denker

ฉันเข้าใจว่าอาร์เรย์ของจำนวนเต็มเป็นมูลค่าส่งคืนที่จะรวมอยู่ใน "หรือดิบออก"
Marv

2
@Marv ไม่ฉันหมายถึงจำนวนไบต์ที่แท้จริงของรูปภาพ (ในรูปแบบทั่วไปที่คุณเลือกบอกว่าppm ) สามารถส่งไปยัง stdout ได้โดยตรง
งานอดิเรกของ Calvin เมื่อ

2
ผลลัพธ์จะต้องเหมือนกันกับตัวอย่างของคุณหรือไม่? ฉันได้รับภาพที่แตกต่างกันเล็กน้อย
DJMcMayhem

1
@DrGreenEggsandHamDJ หากคุณไม่สามารถบอกความแตกต่างด้วยสายตาได้ ไม่จำเป็นต้องมีความสมบูรณ์แบบของพิกเซล
งานอดิเรกของ Calvin

คำตอบ:


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

Python ขนาด 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);}}

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

คำอธิบาย

  • การใช้งาน: ตรงไปตรงมาสวย 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
สำหรับการอ้างอิงในอนาคตคุณสามารถนำเข้าสำหรับคำตอบเฉพาะวิธีเดียวกับที่คุณทำตามปกติ เพียงแค่วางมันไว้นอกร่างกายของวิธีการและนับจำนวนไบต์ คุณสามารถมีคุณสมบัติครบถ้วนคลาสแทนการนำเข้าถ้าคุณต้องการเพียงครั้งเดียวเพื่อบันทึกไม่กี่ไบต์ในบางกรณี
Geobits

นอกจากนี้ยังมีเหตุผลที่คุณนำเข้าjava.io.Fileแทนjava.io.*ใช่หรือไม่
Geobits

ขอบคุณที่รู้ และประการที่สองไม่มีเหตุผล จุดดี.
Marv

ทำไมimport ** static** ไม่ใช่แค่import?
โซโลมอน Ucko

1
เพื่อให้ฉันสามารถโทรImageIO::readและImageIO::writeไม่ต้องเติมเงินImageIO.: เพิ่ม 9 ไบต์ ( static .*) แต่ประหยัด 16 ( ImageIO.สองครั้ง)
Marv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.