Tạo hình ảnh đại diện băng giá cho mùa đông


29

Đó là mùa đông, và thời điểm trong năm đã đến khi trời bắt đầu lạnh (và cho những chiếc khăn trùm đầu đầy màu sắc kỳ lạ bắt đầu xuất hiện ... sớm). Hãy viết một số mã để làm cho hình ảnh đại diện và các hình ảnh khác bị đóng băng, để phù hợp với chủ đề!

Đầu vào

Đầu vào để đệ trình cho thử thách này phải là một hình ảnh (hình ảnh để làm cho đóng băng) và một số (ngưỡng, sẽ được giải thích sau).

Bạn có thể nhập hình ảnh theo bất kỳ cách nào ngôn ngữ của bạn hỗ trợ chúng (đường dẫn tệp hoặc URL làm đối số, lấy nó từ bảng ghi tạm, kéo và thả hình ảnh, v.v.) và ở bất kỳ định dạng nào được liệt kê ở đây thể hiện màu sắc trong RGB (bạn có thể hỗ trợ / yêu cầu RGBA thay thế nếu bạn muốn, nhưng đây không phải là yêu cầu).

Bạn cũng có thể nhập số theo bất kỳ cách nào bạn muốn (đối số dòng lệnh, STDIN, hộp thoại nhập, v.v.), ngoại trừ mã hóa cứng vào chương trình của bạn (ví dụ n=10). Nếu bạn sử dụng đường dẫn tệp / URL cho hình ảnh, nó cũng phải được nhập theo cách này.

Đầu ra

Chương trình phải xử lý hình ảnh theo mô tả bên dưới và sau đó xuất nó theo bất kỳ cách nào bạn muốn (vào một tệp, hiển thị nó trên màn hình, đặt nó vào bảng tạm, v.v.).

Sự miêu tả

Đệ trình nên xử lý hình ảnh với ba bước sau đây. nđề cập đến số mà chương trình của bạn nhận được làm đầu vào cùng với hình ảnh.

  1. Áp dụng độ mờ của bán kính ncho hình ảnh đầu vào bằng cách thay thế từng giá trị R, G và B của từng pixel bằng các giá trị R, G và B trung bình của tất cả các pixel trong khoảng cáchn pixel của Manhattan , bỏ qua tất cả các tọa độ ngoài giới hạn. (Tức là tất cả các pixel trong đó tổng của sự khác biệt trong X và chênh lệch trong Y nhỏ hơn hoặc bằng n.)

    (lưu ý: Tôi đã sử dụng hiệu ứng làm mờ Gaussian cho các hình ảnh ở trên vì có chức năng tích hợp thuận tiện cho nó, vì vậy hình ảnh của bạn có thể trông hơi khác một chút.)

  2. Đặt từng pixel thành một pixel ngẫu nhiên trong khoảng cách n/2pixel ("khoảng cách" được xác định theo cách tương tự như trong bước trước).

    Điều này nên được thực hiện bằng cách lặp qua hình ảnh và đặt từng pixel thành một pixel ngẫu nhiên trong phạm vi này, vì vậy một số pixel có thể biến mất hoàn toàn và một số có thể bị trùng lặp.

    Tất cả các thay đổi phải được áp dụng cùng một lúc. Nói cách khác, sử dụng các giá trị cũ của pixel (sau bước 1 nhưng trước bước này), không phải các giá trị mới sau khi đặt chúng thành pixel ngẫu nhiên.

  3. Nhân giá trị RGB "màu xanh" của mỗi pixel với 1,5, giới hạn ở mức 255 (hoặc bất cứ giá trị tối đa nào cho một dải pixel là) và làm tròn xuống.

Quy tắc

  • Bạn có thể sử dụng các thư viện hình ảnh / chức năng liên quan đến xử lý hình ảnh được tích hợp vào ngôn ngữ của bạn; tuy nhiên, bạn không được sử dụng bất kỳ chức năng nào thực hiện một trong ba nhiệm vụ chính được đề cập trong phần mô tả. Ví dụ: bạn không thể sử dụng một blurchức năng, nhưng một getPixelchức năng là tốt.

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


1
Bước 1 có hai điểm cần làm rõ. Thứ nhất, số liệu nào? Bạn nói Manhattan (L-1) và mô tả L-infinite. Thứ hai, nên xử lý các ranh giới hình ảnh như thế nào: không bao bọc, giảm mẫu số xuống trung bình chỉ trên các pixel bên trong ranh giới? Bước 2 có một điểm cần làm rõ: việc lấy mẫu từ một bản sao của hình ảnh sau bước 1, hoặc có thể thay đổi từ đầu bước 2 lan truyền không? Đối với bước 3, giới hạn ở 255 chỉ phù hợp trong mô hình màu 24 bit và câu hỏi không ở đâu yêu cầu điều đó.
Peter Taylor

@PeterTaylor Tôi đã cố gắng làm rõ tất cả những điểm đó, ngoại trừ điểm đầu tiên. Tôi thực sự không hiểu những gì bạn đang nói; dx <= n && dy <= nlà một đại diện chính xác của khoảng cách Manhattan, phải không?
Doorknob

Không, khoảng cách Manhattan là | dx | + | nhuộm | <= n.
Peter Taylor

@PeterTaylor Được rồi, cảm ơn, tôi cũng đã sửa nó.
Doorknob

1
@stokastic Tôi nghĩ rằng "trong một khoảng cách n / 2 pixel" là một tuyên bố hoàn toàn hợp lệ mà không cần làm tròn / sàn n / 2 (rất hiệu quả, "nổi", tôi nghĩ vậy).
Martin Ender

Câu trả lời:


14

Con trăn 2 - 326 339 358

Lấy đầu vào từ người dùng. Tập tin đầu tiên, sau đó n.

from PIL.Image import*;from random import*
a,N=input()
i=open(a)
d=list(i.getdata())
x,y=i.size
R=range(x*y)
m=lambda p,n,r:[p[i]for i in R if abs(n%x-i%x)+abs(n/y-i/y)<=r]
k=d[:]
for p in R:t=map(lambda x:sum(x)/len(x),zip(*m(k,p,N)));d[p]=t[0],t[1],min(255,t[2]*3/2)
i.putdata([choice(m(d,p,N/2))for p in R])
i.save('t.png')

Điều này có lẽ có thể được chơi golf nhiều hơn nữa: P Cảm ơn @ SP3000 cho ý tưởng chơi gôn!

Đầu vào mẫu: (Windows)

"C:/Silly/Optimizer/Trix/Are/For/Kids.png",7

Chỉnh sửa : Đã sửa lỗi trong đó màu xanh đang được lan truyền (Martin với n = 20 không còn là dòng sông; _;)

Martin với n = 2:

nhập mô tả hình ảnh ở đây

Martin với n = 10:

nhập mô tả hình ảnh ở đây

Martin với n = 20:

nhập mô tả hình ảnh ở đây


3

Python 2 - 617 byte

EDIT: chơi golf một số, có vẻ như FryAmTheEggMan đã đánh bại tôi :)

from PIL import Image
import sys,random
j,i,n=sys.argv
n=int(n)
i=Image.open(i)
w,h=i.size
o=Image.new("RGB",(w,h))
D=list(i.getdata())
D=[D[i*w:i*w+w] for i in range(h)]
O=[]
d=n/2
z=range(-n,n+1)
M=lambda n:[[x,y] for x in z for y in z if abs(x)+abs(y)<=n]
m=M(n)
L=w*h
for i in range(L):
 y,x=i/w,i%w;c=r=g=b=0
 for q in m:
  try:C=D[y+q[1]][x+q[0]];r+=C[0];g+=C[1];b+=C[2];c+=1
  except:pass
 r/=c;g/=c;b/=c
 O.append((r,g,min(b*3/2,255)))
R=lambda:random.randint(-d,d)
for i in range(L):
 x,y=i%w,i/w;u=R();v=R()
 while not(0<x+u<w and 0<y+v<h):u=R();v=R()
 O[y*w+x]=O[(y+v)*w+(x+u)]
o.putdata(O)
o.save("b.png")

3

Java - 1009 byte

eh, tôi nghĩ rằng tôi có thể làm tốt hơn thế này ...

import java.awt.*;import java.io.*;import java.util.*;import javax.imageio.*;class r{public static void main(String[]v)throws Exception{java.awt.image.BufferedImage i=ImageIO.read(new File("y.png"));int n=Byte.valueOf(v[0]),w=i.getWidth(),h=i.getHeight();for(int z=0;z<w*h;z++){int x=z/h,y=z%h,r=0,g=0,b=0,c=0,x2,y2,k;for(x2=x-n;x2<=x+n;x2++){for(y2=y-n;y2<=y+n;y2++){if(Math.abs(x2-x)+Math.abs(y2-y)<=n&&x2>=0&&x2<w&&y2>=0&&y2<h){k=i.getRGB(x2,y2); r+=(k>>16)&0xFF;g+=(k>>8)&0xFF;b+=k&0xFF;c++;}}}i.setRGB(x,y,new Color(r/c,g/c,b/c).getRGB());}int[]t=new int[w*h];for(int z=0;z<h*w;z++){int x=z/h,y=z%h,x2,y2;ArrayList<Integer>e=new ArrayList<>();for(x2=x-n;x2<=x+n;x2++){for(y2=y-n;y2<=y+n;y2++){if(Math.abs(x2-x)+Math.abs(y2-y)<=n/2&&x2>=0&&y2>=0&&x2<w&&y2<h)e.add(i.getRGB(x2,y2));}}int p=e.get((int)(Math.random()*e.size())),b=(int)((p&0xFF)*1.5);t[x*h+y]=new Color((p>>16)&0xFF,(p>>8)&0xFF,b>255?255:b).getRGB();}for(int d=0;d<w*h;d++){i.setRGB(d/h,d%h,t[d]);}ImageIO.write(i,"PNG",new File("n.png"));}}

import java.awt.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
class IceBlur{
    public static void main(String[]v)throws Exception{
        java.awt.image.BufferedImage i=ImageIO.read(new File("blah.png"));
        int n=Byte.valueOf(v[0]),w=i.getWidth(),h=i.getHeight();
        for(int z=0;z<w*h;z++){
            int x=z/h,y=z%h,r=0,g=0,b=0,c=0,x2,y2,k;
            for(x2=x-n;x2<=x+n;x2++){
                for(y2=y-n;y2<=y+n;y2++){
                    if(Math.abs(x2-x)+Math.abs(y2-y)<=n&&x2>=0&&x2<w&&y2>=0&&y2<h){
                        k=i.getRGB(x2,y2);
                        r+=(k>>16)&0xFF;
                        g+=(k>>8)&0xFF;
                        b+=k&0xFF;
                        c++;}}}i.setRGB(x,y,new Color(r/c,g/c,b/c).getRGB());}
        int[]t=new int[w*h];
        for(int z=0;z<h*w;z++){
            int x=z/h,y=z%h,x2,y2;
            ArrayList<Integer>e=new ArrayList<>();
            for(x2=x-n;x2<=x+n;x2++){
                for(y2=y-n;y2<=y+n;y2++){
                    if(Math.abs(x2-x)+Math.abs(y2-y)<=n/2&&x2>=0&&y2>=0&&x2<w&&y2<h)e.add(i.getRGB(x2, y2));}}
            int p=e.get((int)(Math.random()*e.size())),b=(int)((p&0xFF)*1.5);
            t[x*h+y]=new Color((p>>16)&0xFF,(p>>8)&0xFF,b>255?255:b).getRGB();}
        for(int d=0;d<w*h;d++){i.setRGB(d/h, d%h, t[d]);}
        ImageIO.write(i,"PNG",new File("blah2.png"));}}

Martin với n = 5:

nhập mô tả hình ảnh ở đây

n = 20:

nhập mô tả hình ảnh ở đây

Tôi với 10:

nhập mô tả hình ảnh ở đây


Đã được một thời gian kể từ khi tôi có bất cứ điều gì, nhưng bạn không thể làm gì k&0xFF00? Hơn nữa, bạn không thể sử dụng 255thay 0xFFthế?
FryAmTheEggman

3

C, 429 (391 + 38 để xác định cờ)

i,R,G,B,q;char*c,t[99];main(r,a,b,k,z,p){scanf("%*[^ ]%d%*6s%d%[^N]%*[^R]R\n",&a,&b,t);int j=a*b,d[j],e[j];F(c=d;c<d+j;*c++=getchar());F(;i<j;e[i++]=X<<24|B/q<<16|G/q<<8|R/q,R=G=B=q=0)F(k=0;k<j;)p=d[k++],D<r&&(++q,R+=p&X,G+=p>>8&X,B+=p>>16&X);F(i=!printf("P7\nWIDTH %d\nHEIGHT %d%sNDHDR\n",a,b,t);i<j;d[i++]=e[k])F(;k=rand()%j,D>r/2;);F(c=d;q<j*4;i=(q%4-2?2:3)*c[q]/2,putchar(i>X?X:i),++q);}

Định dạng đầu vào: pamtệp không có nhận xét hoặc khoảng trắng thừa trong tiêu đề, nội dung được truyền qua STDIN.

n đối số là bắt buộc (chúng có thể là bất cứ điều gì).

Định dạng đầu ra: pamtập tin trong STDOUT.

Để biên dịch:

gcc -DX=255 -DF=for "-DD=z=abs(k-i),z/b+z%a" -Wl,--stack,33554432 -funsigned-char icyavatars.c -o icyavatars

-Wl,--stack,33554432tăng kích thước ngăn xếp; điều này có thể được thay đổi hoặc loại bỏ, tùy thuộc vào kích thước của hình ảnh được xử lý (chương trình yêu cầu kích thước ngăn xếp lớn hơn hai lần số pixel lần 4).

-funsigned-charcó gcc sử dụng unsigned charthay vì signed charcho char. Các tiêu chuẩn C cho phép một trong hai tùy chọn này và tùy chọn này chỉ cần ở đây vì gcc sử dụng signed chartheo mặc định.

Để chạy (n = 5):

./icyavatars random argument here fourth fifth < image.pam > output.pam

Lưu ý: Nếu biên dịch trên Windows, stdio.h, fcntl.hio.hphải được bao gồm, và đoạn mã sau thêm vào khi bắt đầu main()theo thứ tự cho các chương trình để đọc / ghi vào STDIN / STDOUT như nhị phân, không văn bản, suối (điều này là không thích hợp trên Linux, nhưng Windows sử dụng \r\nthay vì \ncho các luồng văn bản).

setmode(fileno(stdin), _O_BINARY);
setmode(fileno(stdout), _O_BINARY);

Phiên bản đã bình luận

int i,R,G,B,q;
char *c,t[99];
main(r,a,b,k,z,p){
    // read all of header
    // save a large chunk to t, save width to a, save height to b
    scanf("%*[^ ]%d%*6s%d%[^N]%*[^R]R\n", &a, &b, t);
    // create arrays for holding the pixels
    int j = a * b, d[j], e[j];
    // each pixel is 4 bytes, so we just read byte by byte to the int arrays
    for(c = d; c < d + j; ++c)
        *c=getchar();

    // calculating average rgb
    for(i = 0; i < j; ++i){
        // check every pixel; add r/g/b values to R/G/B if manhattan distance < r-1
        for(k = 0; k < j; ++k){
            // pixel being checked
            p = d[k];
            // manhattan distance
            z = abs(k - i)/b + abs(k - i)%a;
            if(z < r){
                // extract components and add
                ++q;
                R += p & 255;
                G += p >> 8 & 255;
                B += p >> 16 & 255;
            }
        }
        // set pixel in e (not d) to average RGB and 255 alpha
        e[i]= 255<<24 | B/q<<16 | G/q<<8 | R/q;
        // clear temporary variables
        R = G = B = q = 0;      
    }

    // print header
    printf("P7\nWIDTH %d\nHEIGHT %d%sNDHDR\n",a,b,t);
    // choose random pixels
    for(i = 0; i < j; ++i){
        // loop until randomly generated integer represents a pixel that is close enough
        do{
            k = rand() % j;
            // manhattan distance
            z = abs(k - i)/b + abs(k - i)%a;
        }while(z > r/2);
        // set d to the new pixel value
        d[i] = e[k];
    }
    // apply blue scaling and output
    for(c = d, q = 0; q < j * 4; ++q){
        // 3/2 if blue component, 1 otherwise
        i = (q % 4 - 2 ? 2 : 3)*c[q]/2;
        // cap components at 255
        putchar(i > 255 ? 255 : i);
    }
}

Martin với n = 10:

Martin với n = 10

Martin với n = 20:

Martin với n = 20

Martin với n = 100:

Martin với n = 100


1

R, 440 ký tự

f=function(n,p){a=png::readPNG(p);b=a;N=nrow(a);M=ncol(a);r=row(a[,,1]);c=col(a[,,1]);for(i in 1:N)for(j in 1:M)b[i,j,]=apply(a,3,function(x)mean(x[abs(r-i)+abs(c-j)<=n]));for(i in 1:N)for(j in 1:M){g=which(abs(r-i)+abs(c-j)<=n/2,arr.ind=T);o=sample(1:nrow(g),1);b[i,j,]=b[g[o,1],g[o,2],]};b[,,3]=b[,,3]*1.5;b[b>1]=1;png(w=M,h=N);par(mar=rep(0,4));plot(0,t="n",xli=c(1,M),yli=c(1,N),xaxs="i",yaxs="i",ax=F);rasterImage(b,1,1,M,N);dev.off()}

Với ngắt dòng cho mức độ dễ đọc:

f=function(n,p){
    a=png::readPNG(p) #use readPNG from package png
    b=a
    N=nrow(a)
    M=ncol(a)
    r=row(a[,,1])
    c=col(a[,,1])
    for(i in 1:N){ #braces can be deleted if all is contained in one line
        for(j in 1:M){
            b[i,j,]=apply(a,3,function(x)mean(x[abs(r-i)+abs(c-j)<=n]))
            }
        }
    for(i in 1:N){ #i'm sure this loop could be shortened
        for(j in 1:M){
            g=which(abs(r-i)+abs(c-j)<=n/2,arr.ind=T)
            o=sample(1:nrow(g),1)
            b[i,j,]=b[g[o,1],g[o,2],]
            }
        }
    b[,,3]=b[,,3]*1.5 #readPNG gives RGB values on a [0,1] range, so no need to round
    b[b>1]=1
    png(w=M,h=N)
    par(mar=rep(0,4))
    plot(0,t="n",xli=c(1,M),yli=c(1,N),xaxs="i",yaxs="i",ax=F)
    rasterImage(b,1,1,M,N)
    dev.off()
    }

Đầu vào mẫu: f(2,"avatar.png")

Kết quả với n = 2

Ảnh đại diện của tôi với n = 2

... với n = 10

với n = 10

... với n = 20

với n = 20

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.