이미지를 Rainbowlify


23

이 문제는 이미지에서 색조를 점진적으로 변경하여 다음과 같이 예쁜 그림을 만듭니다.

큰 별이 빛나는 밤 ( 원본 )

도전

음수가 아닌 두 개의 정수와 선택한 일반적인 이미지 파일 형식의 이미지를 사용하는 프로그램 또는 함수를 작성하십시오 (이미지 또는 원시 이미지 데이터에 대한 경로를 취할 수 있음).

첫 번째 정수는 사이클이라고 하고 두 번째 정수는 오프셋 이라고 부릅니다 .

우리는 또한 부동 소수점 정의 할 것이다 단계 360 번으로 순환 하여 이미지의 영역, 또는으로 나눈 값을 step = 360 * cycles / (image width * image height).

이미지의 각 픽셀 P 에 대해 한 번에 한 행씩 왼쪽에서 오른쪽으로, 위에서 아래로 (픽셀이 문자 인 경우 읽기 순서로) 이동하면 다음을 수행하십시오.

  1. 증가 색조P 에 의해 오프셋 (필요한 경우 0에서 360의 주위에 루핑)도.

  2. 그런 다음 단계적으로 오프셋 을 늘리십시오 .

결과 이미지를 일반적인 이미지 파일 형식으로 저장, 표시 또는 출력하지 않습니다.

이 절차는 점진적으로 만드는 이미지의 모든 픽셀의 색상을 증가 사이클을 주위에 전체 루프를 색조 무지개 에 의해 처음 색조를 상쇄에 의해 시작 오프셋 .

되면 사이클 1 및 오프셋 위 나이트 별 화상과 0 인 풀 컬러 사이클 거기 사이의 위쪽 및 아래쪽의 화소의 행은 실제적으로 색조 변화하지만 없다.

세부

  • 사이클 은 음이 아닌 정수일 수 있지만 오프셋 이 0에서 359 사이 라고 가정 할 수 있습니다 .

  • 사이클이 0, 이미지의 모든 픽셀은 색상이 정확히으로 이동해야합니다 오프셋 이후 단계는 너무 0이어야합니다. (이 경우 오프셋 이 0이면 이미지가 전혀 변경되지 않습니다.)

  • 원하는 경우 사이클오프셋 이 플로트로 입력 된다고 가정 할 수 있습니다 (예 : 1.0대신 1). (나는 정수가 될 필요가 없다는 것을 알고 있습니다. 어려움을 간단하게 만듭니다.)

  • "색조"는 HSL / HSV 색상 모델 에서 일반적으로 사용되는 RGB 색상 공간 버전을 나타냅니다 .

기발한:

강

사이클 = 1, 오프셋 = 0 :

강 출력 1

사이클 = 1, 오프셋 = 180 :

강 출력 2

기발한:

구체

사이클 = 2, 오프셋 = 60 :

구 출력

기발한:

일몰
( ArtOfCode 감사 합니다 .)

사이클 = 1, 오프셋 = 120 :

일몰 출력

기발한:

손잡이
( 도움말 감사합니다 .)

사이클 = 1, 오프셋 = 0 :

손잡이 출력 1

사이클 = 4, 오프셋 = 0 :

손잡이 출력 2

사이클 = 200, 오프셋 = 0 :

손잡이 출력 3

사이클 = 30000, 오프셋 = 0 :

손잡이 출력 4

(이러한 이미지는 이미지 압축으로 인해 완벽한 픽셀이 아닐 수 있습니다.)

채점

바이트 단위의 가장 짧은 코드가 이깁니다. Tiebreaker가 더 높은 투표 응답입니다.

자신의 멋진 테스트 이미지를 게시하는 답변은 나에게 더 많은 브라우니 포인트를 얻습니다.


6
Doorknob이 냄비를 피우는 것처럼 보입니다.
Denker

반환 값이 "또는 output raw"에 포함될 때 정수 배열을 가정합니까?
Marv

2
@Marv 아니요. 이미지의 원시 바이트 (선택한 공통 형식, ppm )를 stdout으로 직접 파이프 할 수 있음을 의미합니다.
Calvin 's Hobbies

2
출력이 예제와 동일해야합니까? 이미지 가 약간 다릅니다.
DJMcMayhem

1
@DrGreenEggsandHamDJ 시각적으로 차이를 말할 수 없다면 아마 괜찮을 것입니다. 픽셀 완성이 필요하지 않습니다 (어쨌든 이미지가 손실되어 이미지를 압축했을 수 있습니다).
Calvin 's Hobbies

답변:


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

삼

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?
Solomon Ucko

1
그래서 내가 전화를 할 수있어 것을 ImageIO::read하고 ImageIO::write앞에 추가 할 필요없이 ImageIO.이 (9 바이트 추가 static .*16 ()를하지만, 저장 ImageIO.회).
Marv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.