검은 색과 흰색 무지개


60

흑백 픽셀 만있는 이미지와 흰색 픽셀 인 (x, y) 위치가 지정된 경우 다른 흰색 픽셀을 순회하는 경로에서만 (x, y)에서 최소 맨해튼 거리 를 기준으로 흰색 픽셀의 색상을 지정하십시오 .

색상 이 지정된 픽셀 의 색조 는 (x, y)와의 거리에 비례해야하므로 (x, y)의 픽셀은 색조가 0 ° (빨간색)이고 가장 먼 픽셀이 (x, y)입니다 색조는 360 ° (빨간색)이며 다른 색조는 매끄럽고 직선적으로 혼합됩니다. 채도 값을 모두 100 %이어야한다.

흰색 픽셀이 다른 흰색 픽셀을 통해 (x, y)에 연결되어 있지 않으면 흰색이어야합니다.

세부

  • 입력은 이미지 또는 원시 이미지 데이터의 파일 이름과 x 및 y 정수로 구성됩니다.
  • 출력 이미지는 파일에 저장되거나 일반적인 이미지 파일 형식으로 stdout으로 파이프 처리되거나 간단하게 표시 될 수 있습니다.
  • x 값은 가장 왼쪽 픽셀에서 0이며 오른쪽으로 갈수록 증가합니다. y 값은 최상위 픽셀에서 0이며 아래로 갈수록 증가합니다. (x, y)는 항상 이미지 경계에 있습니다.
  • 전체 프로그램과 기능이 모두 허용됩니다.

바이트 단위의 가장 짧은 코드가 이깁니다.

공간을 절약하기 위해이 이미지들은 모두 축소되었습니다. 클릭하면 전체 크기로 볼 수 있습니다.

입력 이미지 :

예 1 입력

(x,y) = (165,155)(x,y) = (0,0)

예 1 출력 A 예 1 출력 B


다음을 사용하여 이미지 입력 ​​및 출력 (x,y) = (0,0):

예 5 입력 예 5 입력 A


다음을 사용하여 이미지 입력 ​​및 출력 (x,y) = (600,350):

예 2 입력 예 2 출력


다음을 사용하여 이미지 입력 ​​및 출력 (x,y) = (0,0):

예 3 입력 예 3 출력


다음을 사용하여 이미지 입력 ​​및 출력 (x,y) = (0,0):

예 4 입력 예 4 출력


옵션 -30 % 보너스 : 유클리드 거리를 사용하십시오. 알고리즘에 대한 제안은 다음과 같습니다 (일반 개요).

  1. 시작 픽셀이 있습니다.
  2. 해당 픽셀에서 플러드 필.
  3. 플러드 필에 도달 한 모든 픽셀에 대해
  4. 시작 픽셀에서 해당 픽셀로 반 단위 단계로 직선으로 이동하십시오.
  5. 각 단계 int()에서 x 및 y 좌표에 적용 하십시오. 이 좌표의 픽셀이 검은 색이면 중지하십시오. 그렇지 않으면 계속하십시오. (시선 방법입니다.)
  6. 흰색 픽셀 및 / 또는 이전에 상당히 높은 거리 (+10)로 레이블이 지정된 픽셀과 접하는 픽셀에 도달하면 시작 픽셀이됩니다.

보다 메타적인 의미에서이 알고리즘은 시작 / 이미 색상이 지정된 픽셀에서 직선으로 도달 할 수있는 모든 픽셀로 확산 된 다음 가장자리 주위에 "인치"가됩니다. "상당히 더 높은 거리"비트는 알고리즘 속도를 높이기위한 것입니다. 솔직히 유클리드 거리를 구현 하는 방법은 중요하지 않으며 단지 이와 같이 보일뿐입니다.

위의 알고리즘을 사용하여 유클리드 거리에서 첫 번째 예는 다음과 같습니다.

입력 이미지 (x,y) = (165,155)

예 1 입력 여기에 이미지 설명을 입력하십시오


이 도전에 도움을 주신 Calvin'sHobbies와 trichoplax에게 감사드립니다! 즐기세요!


7
골프를 칠 계획은 없지만 이미지 위에 마우스를 올려 놓고 색상을 즉시 업데이트 할 수 있는 Javascript 버전을 만들었습니다 . 여기 테스트 이미지는 내가 좋아하는 작은 이미지하려고 좋을 걸 있도록 빠르게 실행하기에 너무 큰 .
Calvin 's Hobbies

대단해! 골프 버전의 좋은 기반 이 되기에너무 효율적 이라고 생각합니다. =)
flawr

2
미로가 이렇게 착색되면 해결하기가 훨씬 쉽습니다!
mbomb007

마지막 예는 정말 아름답습니다. 입력 이미지가 노이즈입니까?
dylnan December

@ dylnan : 보너스 직전에 예제에 대해 이야기하고 있다면 실제로 미로입니다. 클릭하면 전체 크기로 볼 수 있습니다.
El'endia Starman

답변:


33

MATLAB, 255 (245) 231 바이트

이는 첫째, 다음 이미지 이름을 기대 y하고 x.

I=@input;i=imread(I('','s'));[r,c]=size(i);m=zeros(r,c);m(I(''),I(''))=1;M=m;d=m;K=[1,2,1];for k=1:r*c;d(m&~M)=k;M=m;m=~~conv2(m,K'*K>1,'s');m(~i)=0;end;z=max(d(:));v=[1,1,3];imshow(ind2rgb(d,hsv(z)).*repmat(m,v)+repmat(~d&i,v),[])

먼저 시드 픽셀이 1로 설정되고 거리 누산기 (이미지 크기 모두)가있는 마스크를 만든 다음 다음을 반복하여 홍수 채우기 (또는 원하는 경우 '4 이웃에 대한 dijkstra')를 구현했습니다. 단계 :

  • 4 이웃 커널로 마스크를 복잡하게 만듭니다 (매우 비효율적 인 부분입니다)
  • 마스크의 0이 아닌 모든 픽셀을 1로 설정
  • 이미지의 모든 검은 픽셀을 0으로 설정
  • 이 단계에서 마스크가 변경된 어큐뮬레이터의 모든 값을 k
  • 증가하다 k
  • 마스크에 더 이상 변경 사항이 없을 때까지 반복하십시오 (실제로이 조건을 확인하지는 않지만 이미지의 픽셀 수를 상한으로 사용하십시오. 이는 일반적으로 매우 상한입니다. 그러나 이것은 codegolf =입니다)

이것은 거리 누산기에서 모든 픽셀의 맨해튼 거리와 시드 픽셀까지 남습니다. 그런 다음 주어진 색상 범위를 통해 새 이미지를 만들고 "첫 번째"색조를 값 0에 매핑하고 "마지막"색조를 최대 거리에 매핑합니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

보너스로, 거리 계산 방법에 대한 예쁜 그림입니다. 밝을수록 멀어집니다.

여기에 이미지 설명을 입력하십시오


3
이것은 내 딸이 그림을 그리기 위해 인쇄하고 싶은 물건입니다.
rayryeng-복원 모니카

@rayryeng 템플릿은 El'endia Starman의 작품이며 내 것이 아닙니다 =)
flawr

여전히 이미지에 색상을 넣습니다. : D. 마지막 단계를 수행했습니다.
rayryeng-복원 모니카

4
나는 감동. 도전 과제를 거의 이해할 수 없었습니다. lol
zfrisch

솔직히, 내가 사용하고 싶은 것은 풍경을 만드는 것입니다.
corsiKa

3

블리츠 2D / 3D , 3068 * 0.7 = 2147.6

이것이 유클리드 알고리즘에 대한 참조 구현입니다.

image=LoadImage("HueEverywhere_example1.png")
Graphics ImageWidth(image),ImageHeight(image)
image=LoadImage("HueEverywhere_example1.png")
x=0
y=0
w=ImageWidth(image)
h=ImageHeight(image)
Type start
Field x,y
Field dis#
Field nex.start
End Type
Type cell
Field x,y
Field dis#
End Type
Type oldCell
Field x,y
Field dis#
End Type
initCell.start=New start
initCell\x=x
initCell\y=y
initCell\dis=1
Dim array#(w,h)
imgBuff=ImageBuffer(image)
LockBuffer(imgBuff)
s.start=First start
colr=col(0,0,0)
colg=col(0,0,1)
colb=col(0,0,2)
newcol=colr*256*256+colg*256+colb
WritePixelFast(s\x,s\y,newcol,imgBuff)
While s<>Null
c.cell=New cell
c\x=s\x
c\y=s\y
c\dis=s\dis
While c<>Null
For dy=-1To 1
For dx=-1To 1
If dx*dy=0And dx+dy<>0
nx=c\x+dx
ny=c\y+dy
ndis#=s\dis+Sqr#((nx-s\x)*(nx-s\x)+(ny-s\y)*(ny-s\y))
If nx >= 0And nx<w And ny >= 0And ny<h
If KeyHit(1)End
pixcol=ReadPixelFast(nx,ny,imgBuff)
If pixcol<>-16777216
If array(nx,ny)=0Or ndis<array(nx,ny)
check=1
steps=Ceil(dis)*2
For k=0 To steps
r#=k*1./steps
offx#=Int(s\x+(c\x-s\x)*r)
offy#=Int(s\y+(c\y-s\y)*r)
pixcol2=ReadPixelFast(offx,offy,imgBuff)
If pixcol2=-16777216
check=0
Exit
EndIf
Next
If check
array(nx,ny)=ndis
newCell.cell=New cell
newCell\x=nx
newCell\y=ny
newCell\dis=ndis
EndIf
EndIf
EndIf
EndIf
EndIf
Next
Next
o.oldCell=New oldCell
o\x=c\x
o\y=c\y
o\dis=c\dis
Delete c
c=First cell
Wend
For o.oldCell=Each oldCell
bordersWhite=0
For dy=-1To 1
For dx=-1To 1
If dx<>0Or dy<>0
nx=o\x+dx
ny=o\y+dy
If nx>=0And nx<w And ny>=0And ny<h
pixcol=ReadPixelFast(nx,ny,imgBuff)
If (pixcol=-1And array(nx,ny)=0)Or array(nx,ny)>o\dis+9
bordersWhite=1
Exit
EndIf
EndIf
EndIf
Next
If bordersWhite Exit
Next
If bordersWhite
ns.start=New start
ns\x=o\x
ns\y=o\y
ns\dis=o\dis
s2.start=First start
While s2\nex<>Null
If ns\dis<s2\nex\dis
Exit
EndIf
s2=s2\nex
Wend
ns\nex=s2\nex
s2\nex=ns
EndIf
Delete o
Next
EndIf
s2=s
s=s\nex
Delete s2
Wend
maxDis=0
For j=0To h
For i=0To w
If array(i,j)>maxDis maxDis=array(i,j)
Next
Next
For j=0To h
For i=0To w
dis2#=array(i,j)*360./maxDis
If array(i,j) <> 0
colr=col(dis2,0,0)
colg=col(dis2,0,1)
colb=col(dis2,0,2)
newcol=colr*256*256+colg*256+colb
WritePixelFast(i,j,newcol,imgBuff)
EndIf
Next
Next
UnlockBuffer(imgBuff)
DrawImage image,0,0
Function col(ang1#,ang2#,kind)
While ang1>360
ang1=ang1-360
Wend
While ang1<0 
ang1=ang1+360
Wend
While ang2>180
ang2=ang2-360
Wend
While ang2<-180
ang2=ang2+360
Wend
a3#=ang2/180.
If ang1>300
diff#=(ang1-300)/60.
r=255
g=0
b=255*(1-diff)
ElseIf ang1>240
diff#=(ang1-240)/60.
r=255*diff
g=0
b=255
ElseIf ang1>180
diff#=(ang1-180)/60.
r=0
g=255*(1-diff)
b=255
ElseIf ang1>120
diff#=(ang1-120)/60.
r=0
g=255
b=255*diff
ElseIf ang1>60
diff#=(ang1-60)/60.
r=255*(1-diff)
g=255
b=0
Else
diff#=(ang1-00)/60.
r=255
g=255*diff
b=0
EndIf
If a3>0
r2=r+a3*(255-r)
g2=g+a3*(255-g)
b2=b+a3*(255-b)
Else
r2=r+a3*r
g2=g+a3*g
b2=b+a3*b
EndIf
If r2>255
r2=255
ElseIf r2<0
r2=0
EndIf
If g2>255
g2=255
ElseIf g2<0
g2=0
EndIf
If b2>255
b2=255
ElseIf b2<0
b2=0
EndIf
If kind=0
Return r2
ElseIf kind=1
Return g2
ElseIf kind=2
Return b2
Else
Return 0
EndIf
End Function

사실, 나는 이것이 원본과 비교할 수없는 것을 싫어합니다. (실수로 5305 바이트입니다.) 실제로, 모든 것에 하나의 문자 변수 이름을 사용하여 훨씬 더 많은 바이트를 제거 할 수는 있지만 이미 충분히 어리 석습니다. 그리고 그것은 곧 이길 수 없습니다. :피


2

C ++ / SFML : 1271 1235 1226 바이트

사용자에게 감사 -36 바이트 202729 Zacharý 덕분에 -9 바이트

#include<SFML\Graphics.hpp>
#include<iostream>
#define V std::vector
#define P e.push_back
#define G(d,a,b,c) case d:return C(a,b,c);
#define FI(r,s)(std::find_if(e.begin(),e.end(),[&a](const T&b){return b==T{a.x+(r),a.y+(s),0};})!=e.end())
using namespace sf;using C=Color;struct T{int x,y,c;bool operator==(const T&a)const{return x==a.x&&y==a.y;}};int max(V<V<int>>&v){int m=INT_MIN;for(auto&a:v)for(auto&b:a)m=b>m?b:m;return m;}C hsv2rgb(int t){int ti=t/60%6;float f=t/60.f-ti,m=(1.f-f)*255,n=f*255;switch(ti){G(0,255,n,0)G(1,m,255,0)G(2,0,255,n)G(3,0,m,255)G(4,n,0,255)G(5,255,0,m)default:throw std::exception();}}void r(Image&a,int x,int y){auto d=a.getSize();V<V<int>>m(d.x,V<int>(d.y));int i=0,j,c=0,t;for(;i<d.y;++i)for(j=0;j<d.x;++j)m[j][i]=a.getPixel(j,i)==C::Black?-1:0;V<T>e{{x,y,1}};while(e.size()){V<T>t=std::move(e);for(auto&a:t){m[a.x][a.y]=a.c;if(a.x>0&&m[a.x-1][a.y]==0&&!FI(-1,0))P({a.x-1,a.y,a.c+1});if(a.y>0&&m[a.x][a.y-1]==0&&!FI(0,-1))P({a.x,a.y-1,a.c+1});if(a.x<m.size()-1&&m[a.x+1][a.y]==0&&!FI(1,0))P({a.x+1,a.y,a.c+1});if(a.y<m[0].size()-1&&m[a.x][a.y+1]==0&&!FI(0,1))P({a.x,a.y+1,a.c+1});}}c=max(m)-1;for(i=0,j;i<d.y;++i)for(j=0;j<d.x;++j)if(m[j][i]>0)a.setPixel(j,i,hsv2rgb(360.f*(m[j][i]-1)/c));}

sf::Image파라미터가 또한 출력된다 (변형된다). 당신은 그것을 다음과 같이 사용할 수 있습니다 :

sf::Image img;
if (!img.loadFromFile(image_filename))
    return -1;

r(img, 0, 0);

if (!img.saveToFile(a_new_image_filename))
    return -2;

첫 번째 매개 변수는 이미지 입력 ​​(및 출력)이고 두 번째 및 세 번째 매개 변수는 시작해야하는 xy매개 변수입니다.


스위치 케이스는 너무 낭비되어 매크로 정의가 유용 할 것입니다 ... 또한``가 필요 setPixel(j, i,hsv2하고 FI(xm,ym) (std::find_if정말로 필요한가?
user202729

G(d,a,b,c)와 사이의 공백을 제거 할 수 있습니다 case d:. 또한 사이 공간 case d:return C(a,b,c)도 불필요하다. (b>m?b:m)괄호를 필요로하지 않으며 조작 순서에 따라 (t/60)%6=> t/60%6.
Zacharý

당신은 아마도 이름을 변경해야 xm하고 ym짧은 변수 이름에
재커리

나는 사이의 공간을 제거 할 수 있다고 생각 G(d,a,b,c)하고 case, FI, ti, 그리고 hsv2rgb각각의 짧은 이름으로 대체 할 수있다.
Zacharý

1

C ++, 979969898 859848 바이트

#include<cstdio>
#include<cstdlib>
#define K 400
#define L 400
#define M (i*)malloc(sizeof(i))
#define a(C,X,Y)if(C&&b[Y][X].c){t->n=M;t=t->n;b[Y][X].d=d+1;t->n=0;t->c=X;t->d=Y;}
#define A(n,d)case n:d;break;
#define F fgetc(f)
#define W(A,B) for(A=0;A<B;A++){
struct i{int c;int d;int v;i*n;}b[L][K]={0},*h,*t;float m=0;int main(){FILE*f=fopen("d","r+b");int x,y,d=0;W(y,L)W(x,K)b[y][x].c=F<<16|F<<8|F;}}rewind(f);x=165,y=155;h=M;h->c=x;h->d=y;b[y][x].d=d;t=h;while(h){i*p=b[h->d]+h->c;if(p->v)h=h->n;else{p->v=1;x=h->c;y=h->d;d=p->d;m=d>m?d:m;a(x>0,x-1,y)a(x<K-1,x+1,y)a(y>0,x,y-1)a(y<L-1,x,y+1)}}W(y,L)W(x,K)i p=b[y][x];unsigned char n=-1,h=p.d/(m/n),R=h%43*6,Q=n*(n-(n*R>>8))>>8,t=n*(n-(n*(n-R)>>8))>>8,r,g,b;switch(h/43){A(0,n,t,0)A(1,Q,n,0)A(2,0,n,t)A(3,0,Q,n)A(4,t,0,n)A(5,n,0,Q)}d=h?r|g<<8|b<<16:p.c?-1:0;fwrite(&d,1,3,f);}}}
  • 입력 : RGB 데이터 파일 (파일에 포함 : d)
  • 출력 : RGBA RGB 데이터 파일 (파일로 출력 : d)
  • 예 : 변환 깊이 8 크기 "400x400"test.png d.rgb && mv -f d.rgb d && g ++ -o test main.c && ./test
  • 참고 : 이미지 크기와 시작은 소스 수준에서 제어됩니다. 문제가 있다면 50 바이트 또는 그 이상을 추가하십시오. 정직하게 변경하지는 않았습니다.

직접 "ungolf"는 아니지만 이것은 제가 먼저 조롱 한 C 프로토 타입이었습니다.

#include "stdio.h"
#include "stdlib.h"

struct i{
    unsigned int c;
    int d;
    int v;
}b[400][400]={0};

typedef struct q{
    int x;
    int y;
    struct q *n;
}q;
q *qu;
q *t;
float m=0;
int get_dist(int x, int y)
{
    int d = 0;

}

void flood(int x,int y,int d){
    qu=malloc(sizeof(q));
    qu->x=x;qu->y=y;b[y][x].d=d;
    t=qu;
    while(qu){
        struct i *p = &b[qu->y][qu->x];
        if(p->v){qu=qu->n; continue;}
        p->v=1;x=qu->x;y=qu->y;d=p->d;
        #define a(C,X,Y) if(C&&b[Y][X].c){t->n=malloc(sizeof(q));t=t->n;b[Y][X].d=d+1;t->n=0;t->x=X;t->y=Y;}
        a(x>0,x-1,y);
        a(x<399,x+1,y);
        a(y>0,x,y-1);
        a(y<399,x,y+1);
        m=p->d>m?p->d:m;
    }
}

unsigned int C(int h)
{
    int r=0,g=0,b=0;
    int s=255,v=255;
    unsigned char R, qq, t;

    R = h%43*6; 

    qq = (v * (255 - ((s * R) >> 8))) >> 8;
    t = (v * (255 - ((s * (255 - R)) >> 8))) >> 8;

    switch (h / 43){
        case 0: r = v; g = t; break;
        case 1: r = qq; g = v; break;
        case 2: g = v; b = t; break;
        case 3: g = qq; b = v; break;
        case 4: r = t; b = v; break;
        case 5: r = v; b = qq; break;
    }

    return r|(g<<8)|(b<<16)|255<<24;
}

#define F fgetc(f)
int main()
{
    FILE *f=fopen("d", "r+b");
    for(int y=0; y<400; y++){
        for(int x=0; x<400; x++){
            b[y][x].c = (F<<24)|(F<<16)|(F<<8);
        }
    }
    rewind(f);
    flood(165,155,1);
    m/=255.f;
    for(int y=0; y<400; y++){
        for(int x=0; x<400; x++){
            struct i p = b[y][x];
            unsigned int h = C(p.d/m);
            int o = p.c?-1:255<<24;
            if(p.d)fwrite(&h,4,1,f);
            else fwrite(&o,4,1,f);
        }
    }
}

많은 개념들이 비슷하게 남아 있지만, 수많은 작은 변화들이있을 것입니다. C로 컴파일하려면 C11을 사용해야합니다 (C99는 작동하지만 C11에서만 엄격하게 테스트되었습니다).
나는 새로운 도전을 시도해 보았 기 때문에이 도전을 즐겼다. :).
편집 : 골프가 조금 나아졌습니다.
Edit2 : 두 개의 구조체를 병합하여 내 픽셀 구조체와 큐가 동일하고 매크로 남용이 더 많으며 255를 리플로 사용하여 일련의 부호없는 문자를 정의 할 때 -1로 정의하고 마지막으로 함수 호출을 제거했습니다.
Edit3 : 알파 채널을 저장하는 몇 가지 변수, 연산자 우선 조정 및 RGB로 변환 된 출력을 다시 사용했습니다
.Edit4 : 이제이 작업이 완료되었습니다. 포인터 산술 변경 및 약간의 제어 흐름 조정이 완료되었습니다.


0

Python 3 및 matplotlib, 251 바이트

from pylab import*
def f(i,p):
    h,w,_=i.shape;o=full((h,w),inf);q=[p+(0,)]
    while q:
        x,y,d=q.pop(0)
        if w>x>=0and h>y>=0and i[y,x,0]:o[y,x]=d;i[y,x]=0;d+=1;q+=[(x-1,y,d),(x+1,y,d),(x,y-1,d),(x,y+1,d)]
    imshow(i);imshow(o,'hsv')

입력은 matplotlib의 imshow()함수에 의해 반환되는 MxNx3 numpy 배열 입니다. 입력은 기능에 의해 수정되므로 미리 복사해야합니다. matplotlib이 "대화식"모드 인 경우 이미지를 자동으로 표시합니다. 그렇지 않으면 show()다른 7 바이트에 대한 호출을 추가해야합니다.

출력은 먼저 원본 이미지를 표시 한 다음 그 위에 무지개 이미지를 표시하여 생성됩니다. Matplotlib은 inf와 nan을 투명하게 처리하여 흑백 이미지가 잘 보이도록합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.