सर्दियों के मौसम के लिए बर्फीले अवतार चित्र बनाएं


29

यह सर्दियों का मौसम है, और साल का समय आ गया है कि ठंड शुरू हो जाए (और अजीब रंगीन हेडक्लॉथ दिखाई देने लगे ... जल्द ही)। आइये अवतार चित्र और अन्य चित्र बनाने के लिए कुछ कोड लिखें, ताकि विषय को फिट किया जा सके!

इनपुट

इस चुनौती को प्रस्तुत करने के लिए इनपुट एक छवि (जमे हुए बनाने के लिए छवि) और एक संख्या (दहलीज, जिसे बाद में समझाया जाएगा) होना चाहिए।

आप किसी भी तरह से छवि का इनपुट कर सकते हैं, आपकी भाषा उनका समर्थन करती है (एक फ़ाइल पथ या URL एक तर्क के रूप में, इसे क्लिपबोर्ड से लेना, एक छवि को खींचना और छोड़ना, आदि) और यहां सूचीबद्ध किसी भी प्रारूप में आरजीबी में रंग व्यक्त करता है (आप यदि आप चाहें तो RGBA का समर्थन / आवश्यकता कर सकते हैं, लेकिन यह आवश्यकता नहीं है)।

आप किसी भी तरह से नंबर को इनपुट कर सकते हैं (जैसे कि कमांड लाइन तर्क, एसटीडीआईएन, इनपुट डायलॉग, आदि), हार्डकॉडिंग के अपवाद के साथ इसे अपने प्रोग्राम (पूर्व n=10) में करें। यदि आप छवि के लिए फ़ाइल पथ / URL का उपयोग करते हैं, तो इसे इस तरीके से भी इनपुट होना चाहिए।

उत्पादन

कार्यक्रम को नीचे दिए गए विवरण के अनुसार छवि को संसाधित करना होगा और फिर इसे किसी भी तरह से आउटपुट करना होगा (एक फ़ाइल में, इसे स्क्रीन पर दिखाते हुए, इसे क्लिपबोर्ड पर रखकर, आदि)।

विवरण

सबमिशन को निम्नलिखित तीन चरणों के साथ छवि को संसाधित करना चाहिए। nउस संख्या को संदर्भित करता है जिसे आपके प्रोग्राम को छवि के साथ इनपुट के रूप में प्राप्त हुआ है।

  1. nप्रत्येक पिक्सेल के R, G, और B मानों की औसत R, G और B मानों के साथ पिक्सेल के मैनहट्टन दूरी के भीतर सभी पिक्सेल के रिप्लेसमेंट द्वारा त्रिज्या का एक धब्बा लागू करें n, सभी आउट-ऑफ-बाउंड्स निर्देशांक को अनदेखा करते हुए। (यानी सभी पिक्सेल जहां X में अंतर और Y में अंतर से कम या इसके बराबर है n।)

    (ध्यान दें: मैंने ऊपर की छवियों के लिए एक गाऊसी ब्लर का उपयोग किया था क्योंकि इसके लिए एक सुविधाजनक अंतर्निहित फ़ंक्शन था, इसलिए आपकी छवियां थोड़ी अलग दिख सकती हैं।)

  2. पिक्सेल की दूरी के भीतर प्रत्येक पिक्सेल को एक यादृच्छिक पिक्सेल पर सेट करें n/2("दूरी" को पिछले चरण की तरह ही परिभाषित किया गया है)।

    यह छवि के माध्यम से लूपिंग और प्रत्येक पिक्सेल को इस रेंज में एक यादृच्छिक पिक्सेल पर सेट करने के लिए किया जाना चाहिए, इसलिए कुछ पिक्सेल पूरी तरह से गायब हो सकते हैं और कुछ डुप्लिकेट हो सकते हैं।

    सभी परिवर्तन एक ही समय में लागू होने चाहिए। दूसरे शब्दों में, पिक्सेल के पुराने मानों का उपयोग करें (चरण 1 के बाद लेकिन इस चरण से पहले), उन्हें यादृच्छिक पिक्सेल पर सेट करने के बाद नए मान नहीं।

  3. प्रत्येक पिक्सेल के "ब्लू" RGB मान को 1.5 से गुणा करें, इसे 255 पर कैपिंग करें (या पिक्सेल के बैंड के लिए अधिकतम मान जो भी हो) और नीचे राउंडिंग।

नियम

  • आप अपनी भाषा में निर्मित छवि पुस्तकालयों / छवि प्रसंस्करण से संबंधित कार्यों का उपयोग कर सकते हैं; हालाँकि, आप वर्णन में वर्णित तीन प्रमुख कार्यों में से एक का प्रदर्शन करने वाले किसी भी कार्य का उपयोग नहीं कर सकते हैं। उदाहरण के लिए, आप किसी blurफ़ंक्शन का उपयोग नहीं कर सकते , लेकिन एक getPixelफ़ंक्शन ठीक है।

  • यह , इसलिए बाइट्स में सबसे छोटा कोड जीतता है!


1
चरण 1 में दो बिंदु हैं जिन्हें स्पष्ट करने की आवश्यकता है। सबसे पहले, कौन सा मीट्रिक? आप मैनहट्टन (L-1) कहते हैं और L- अनन्तता का वर्णन करते हैं। दूसरे, छवि की सीमाओं को कैसे नियंत्रित किया जाना चाहिए: कोई भी लपेटन, सीमा के भीतर केवल पिक्सल पर औसत को कम करने के लिए नहीं? चरण 2 में एक बिंदु है जिसे स्पष्ट करने की आवश्यकता है: चरण 1 के बाद छवि की एक प्रति से नमूना है, या चरण 2 के प्रचार में जल्दी से बदल सकता है? चरण 3 के लिए, 255 पर कैपिंग केवल 24-बिट रंग मॉडल में उपयुक्त है, और प्रश्न कहीं भी इसकी आवश्यकता नहीं है।
पीटर टेलर

@PeterTaylor मैंने पहले वाले को छोड़कर उन सभी बिंदुओं को स्पष्ट करने की कोशिश की है। मैं वास्तव में नहीं समझ पा रहा हूं कि आप क्या कह रहे हैं; dx <= n && dy <= nमैनहट्टन दूरी का एक सटीक प्रतिनिधित्व है, है ना?
दरवाज़े

नहीं, मैनहट्टन की दूरी है | dx | + | डाई | <= एन।
पीटर टेलर

@PeterTaylor ठीक है, धन्यवाद, मैंने ठीक किया है।
दरवाज़े

1
@stokastic मुझे लगता है कि "n / 2 पिक्सेल की दूरी के भीतर" गोलाई / फ़्लोरिंग n / 2 के बिना पूरी तरह से मान्य कथन है (इसलिए प्रभावी रूप से, "फ़्लोरेड", मुझे लगता है)।
मार्टिन एंडर

जवाबों:


14

अजगर 2 - 326 339 358

उपयोगकर्ता से इनपुट लेता है। पहले फ़ाइल करें, फिर 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')

यह शायद बहुत अधिक गोल्फ हो सकता है: पी गोल्फ विचारों के लिए @ SP3000 के लिए धन्यवाद!

नमूना इनपुट: (विंडोज)

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

संपादित करें : बग को ठीक किया गया जहां नीला प्रचार किया जा रहा था (n = 20 वाला मार्टिन अब नदी नहीं है; _;)

N = 2 के साथ मार्टिन:

यहाँ छवि विवरण दर्ज करें

N = 10 के साथ मार्टिन:

यहाँ छवि विवरण दर्ज करें

N = 20 के साथ मार्टिन:

यहाँ छवि विवरण दर्ज करें


3

पायथन 2 - 617 बाइट्स

संपादित करें: कुछ गोल्फ, फ्राइअमईएगमैन जैसा दिखता है, हालांकि मुझे हरा दिया है :)

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

जावा - 1009 बाइट्स

एह, मुझे लगा कि मैं इससे बेहतर कर सकता हूं ...

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

N = 5 के साथ मार्टिन:

यहाँ छवि विवरण दर्ज करें

एन = 20:

यहाँ छवि विवरण दर्ज करें

मुझे 10 के साथ:

यहाँ छवि विवरण दर्ज करें


यह कुछ समय के बाद से मैं कुछ भी जावा, लेकिन तुम नहीं कर सकता है k&0xFF00? इसके अलावा, आप के 255स्थान पर उपयोग नहीं कर सकते 0xFF?
FryAmTheEggman

3

सी, 429 (परिभाषित झंडे के लिए 391 + 38)

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

इनपुट प्रारूप: pamहेडर के माध्यम से पारित सामग्री, हेडर में कोई टिप्पणी या अतिरिक्त व्हाट्सएप के साथ फाइल।

n तर्क आवश्यक हैं (वे कुछ भी हो सकते हैं)।

आउटपुट स्वरूप: pamफ़ाइल STDOUT में।

संकलन करना:

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,33554432स्टैक का आकार बढ़ाता है; इसे बदला जा सकता है या हटाया जा सकता है, तस्वीर के आकार के आधार पर संसाधित किया जा सकता है (प्रोग्राम को पिक्सल 4 की संख्या के दोगुने से अधिक एक स्टैक आकार की आवश्यकता होती है)।

-funsigned-charजीसीसी उपयोग है unsigned charके बजाय signed charके लिए char। C मानक इन विकल्पों में से किसी एक के लिए अनुमति देता है, और यह विकल्प केवल यहाँ आवश्यक है क्योंकि signed charडिफ़ॉल्ट रूप से gcc का उपयोग होता है।

चलाने के लिए (n = 5):

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

नोट: यदि विंडोज पर संकलन stdio.h, fcntl.hऔर io.hशामिल किया जाना चाहिए, और main()STDIN / STDOUT को बाइनरी के रूप में पढ़ने / लिखने के लिए प्रोग्राम के शुरू होने के लिए निम्न कोड जोड़ा गया , न कि टेक्स्ट, स्ट्रीम (यह लिनक्स के लिए अप्रासंगिक है, लेकिन पाठ धाराओं के \r\nबजाय विंडोज का उपयोग करता \nहै)।

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

टिप्पणी संस्करण

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

N = 10 के साथ मार्टिन:

मार्टिन एन = 10 के साथ

N = 20 के साथ मार्टिन:

मार्टिन एन = 20 के साथ

मार्टिन के साथ n = 100:

मार्टिन एन = 100 के साथ


1

आर, 440 चरस

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

सुगमता के लिए लाइन ब्रेक के साथ:

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

नमूना इनपुट: f(2,"avatar.png")

N = 2 के साथ परिणाम

N = 2 के साथ मेरा अवतार

... एन = 10 के साथ

n = 10 के साथ

... एन = 20 के साथ

एन = 20 के साथ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.