Generowanie sztuki ASCII

13

Zadanie

Napisać program lub funkcji, które ma obraz szerokości wi wysokości h, oraz dwie liczby całkowite a <= w/2i b <= h/2, i wysyła ASCII sztuki reprezentację obrazu o wymiarach ax b.

Sztuka ascii powinna zostać wygenerowana poprzez następujące kroki (lub inny proces z tymi samymi danymi wyjściowymi):

  1. Zmiana rozmiaru wx hobraz do 2ax 2b. Kolor piksela (x, y)w obrazie o zmienionym rozmiarze powinien być równy średniej kolorów wszystkich pikseli z oryginalnego obrazu w prostokącie z następującymi narożnikami:

    (floor[x * w/2a], floor[y * h/2b])
    (ceil[(x+1) * w/2a], ceil[(y+1) * h/2b])
    
  2. Obraz o zmienionym rozmiarze należy desaturować, biorąc średnią składową koloru czerwonego, zielonego i niebieskiego i ustawiając każdy składnik na tę średnią.

  3. Znak powinien zostać wyprowadzony dla każdego bloku pikseli 2x2, zgodnie z poniższymi zasadami:

    • Niech e = 3 - floor[color/64], gdzie kolor odnosi się do czerwonej składowej koloru lewego górnego piksela (w zakresie 0..255). Niech f, gi hodwołaj się do tej wartości, ale odpowiednio dla pikseli z prawej górnej, lewej dolnej i prawej dolnej.
    • Pozwolić zbyć średnia e, f, g, h.
    • Wypisuje znak odpowiadający poniższemu (biały oznacza piksel, gdzie 3 - floor[color/64]jest zero, a szary oznacza niezerowe).
    • Wszystkie piksele są zerowe= Wyjdź spację ( )
    • Lewy górny piksel jest niezerowylub Prawy górny piksel jest niezerowy= Dane wyjściowe, "jeśli e (or f) >= 2i 'inaczej.
    • Lewy dolny piksel jest niezerowylub Dolny prawy piksel jest niezerowy= Dane wyjściowe, ,jeśli g (or h) >= 2i .inaczej.
    • Najlepsze piksele niezerowelub Niezerowe dolne piksele= Dane wyjściowe-
    • Lewe piksele niezerowelub Prawe piksele niezerowe= Dane wyjściowe;
    • U góry po lewej, u dołu po prawej piksele niezerowe = Wyjście \
    • Prawe górne, lewe dolne piksele niezerowe = Wyjście /
    • Lewy górny piksel zero = Wyjście J
    • Prawy górny piksel zero = Wyjście L
    • Lewy dolny piksel zero = Wyjście 7
    • Dolny prawy piksel zero = Wyjście P
    • Wszystkie niezerowe
      • z = 1: Wyjście *.
      • z = 2: Wyjście C.
      • z = 3: Wyjście #.

Inne uwagi: Wszystkie średnie wykonane w powyższych krokach powinny wykorzystywać dzielenie liczb całkowitych (tj. Zaokrąglanie w kierunku 0).

Możesz użyć biblioteki do odczytu obrazów, ale biblioteki nie mogą być użyte do zmiany rozmiaru i desaturacji.

Wejście

Twój program pobierze trzy części danych:

  • Obraz. Ten obraz może być w dowolnym wybranym przez ciebie formacie (np. PNG, PPM)
  • Szerokość sztuki ascii (w liczbie znaków)
  • Wysokość sztuki ascii (w liczbie znaków)

Dane wejściowe mogą być odczytywane przez STDIN, przekazywane jako argument wiersza poleceń, przechowywane jako zmienna itp.

Wynik

Twój program wyświetli obraz ascii wygenerowany z obrazu i poprzez proces opisany powyżej. Każda linia musi mieć tę samą szerokość (szerokość przekazywana jako dane wejściowe) i nie można dodawać ani usuwać żadnych dodatkowych spacji. Ostatni wiersz może mieć końcowy znak nowej linii, ale nie jest to obowiązkowe. Puste linie (linie tylko spacje) nie mogą być pomijane.

Przykłady

Wszystkie zdjęcia zostały pobrane z Wikipedii i udostępnione jako własność publiczna. Twój program powinien działać dla wszystkich obrazów i prawidłowych danych wejściowych.

Zdjęcie cytryn

Szerokość = 52, Wysokość = 25:


            .-- *** - ----.        
          - ********** L .-- .-- 7 ---- P-       
        .JOT****************. . ********* \.      
       , ****************** L \ J ********** ”.     
      - **********************. J L/     
     JOT*********************; ./**************.L    
    ; ********************* PJ **************; 7;   
   . ********************** ”. *************** ;; *   
   ; **********************; ***************; J *.  
   *********************** ******* P ******** '**;  
   C ********************* C ******* P; *******. **;  
   C ********************** J ***************; **;  
   DO*********************; ****************. **;  
   ********************** „*************** P; **   
  J ********************* P *************** / ***   
 . ********************** 7 ************* „J **;   
 ; ******************** C „” P *********** PJ *** ”   
 „7 ****************** C” „********** P. ** C;    
     „* C *************”; ********* - J ** CP     
      „* C ********** P 7 ** 7 ** P / - **** P      
        - * CCCCC * P- „7 ******** P”       
          „---” --- ”          

Szerokość: 70, Wysokość: 3:

         ---------------------------. .----------------        
    J ***************************** P -J ***************** ***/JOT**;   
  ---------- ********* P --------- '-------------------- - „        

Ziemniaki

Szerokość: 50, Wysokość: 25:





        .JOT---                                     
      .J * P --- J * L--.          
     J *** „L-J *********** -        
    J L       
   ; ***** ”.J **********************     
   J **** 7 ************************ P.  
   ** CC *; . ********* LJ *********** P-   
   ** C * P 'J ********************** -    
   7 * C * L **********************;     
   J * C **; ************************;     
  JC ** C **. ; ; ******** CCC * C ** CCCC **      
  „7 ***** L. 7 ***** CCCCCC **** CC **”      
     - *****. -J - ** C * C * CC ****** CC * ”       
      ; ** CC ***; „** CCC ***** CCCC *;        
       „- **** - - *** CCCCC *** -         
                               „------”           




Próbka clipart

Szerokość: 26, Wysokość: 17:

    -, L 
  J - ** L .C # 
 J '; * PL, C # " 
.PP 7. JC7P  
;; * J ;; , C'C;  
JOT; CC; L C "#   
* L 7-P; *; PC   
7CL *** J * PC '#   
„7 # C * C # P”; P JC # C- 
 J # CCC # L .JC # CJCC ## C;
; # - - #, CCC # CCCCCCCC
; * .- -.C; ; CCCCCCCCCCCC
; **** J ** L; CCCCCCCCCCCC
; *******; „CCCCCCCCCCCP
„*******” CCCCCCCCCCC ”
 „* P-7 *” „CCCCP” -  
               „---       

To jest , więc wygrywa najkrótsza odpowiedź.

es1024
źródło
2
to ciche
kalekie
Kiedy mówisz o wprowadzaniu obrazu, masz na myśli nazwę pliku? Czy rzeczywiste dane obrazu?
sirpercival
@ sirpercival albo jest w porządku
es1024

Odpowiedzi:

6

JavaScript 752, 701

function Z(I,a,b){
    var C=document.createElement('canvas')
    var W=C.width=I.width,H=C.height=I.height,X=C.getContext('2d')
    X.drawImage(I,0,0)
    a*=2,b*=2,W/=a,H/=b
    for(var o=a*b,x=0,y=0,T="",S=[],V;--o;){
        var A=~~(x*W),B=~~(y*H)
        var d=X.getImageData(A,B,(((x+1)*W)<<0)-A,(((y+1)*H)<<0)-B).data
        for(var i=0,p=0,L=d.length;i<L;i+=4)p+=(d[i]+d[i+1]+d[i+2])/3
        p/=L/4
        S[x]=3-(p>>6)
        if(x%2&&y%2){
            var e=V[x-1],f=V[x],g=S[x-1],h=S[x],z=(e+f+g+h)>>2,B=0,c
            B|=e>0?8:0,B|=f>0?4:0,B|=g>0?2:0,B|=h>0?1:0
            c=" ..-';\\J'/;L-7P*".charAt(B)
            c=c=="'"&&(e>1||f>1)?'"':c
            c=c=="."&&(g>1||h>1)?",":c
            T+=c=="*"?z>2?"#":z>1?"C":c:c
        }
        if(++x==a)x=0,y++,V=S,T+=y%2?"\n":"",S=[]
    }
    return T
}

Przykłady:

var items = {
    lemons: {w:52, h:25},
    spuds: {w:50, h:25},
    tux: {w:26, h:17}
};

for(var k in items) {
    var val = items[k];
    var img = new Image();
    img.onload = function() {
        console.log(Z(this,this.w,this.h));
    }
    img.src=k+'.png';
    img.w = val.w;
    img.h = val.h;
}

Cytryny:

            .--JJL--                   .---.        
          -**********-.--          .--7----P-       
        .J***************L.       .*********\.      
       .******************L      \J**********'.     
      .********************.     ;***********L/     
     J*********************;   ./*************.L    
    ,*********************P    -**************;7;   
    **********************'   .***************;;*   
   ;**********************    ;***************;;*.  
   ***********************    *******PP*******'J*;  
   ***********************    *******P;*******.**;  
   ***************7*******    J******;J*******;**;  
   **********************;    ****************.**;  
   **********************'    ***************P;**'  
  J*********************P     ***************/***   
 .**********************      7*************'J**P   
 ;*********************"      '\***********PJ***'   
 "7*******************"        '**********P.***;    
     '***************'         ;*********-J***P     
      '************P'           7*-7**P/-****P      
        -*******P-               '7********P'       
          '---                       -----          

Spuds:

         J---                                     
      .J*P                     .---*L--.          
     J***'                L -J***********-        
    J****                ;****************L       
   ;*****'             .J******************L*     
   J***L7              ************************P  
   **CC*    .         .*********L'***********P-   
   **C*P    '         J**********************-    
   7*C*L              **********************;     
   J*C**.             **********************;     
  JC**C**      .      7********CCC****CCCC**      
  "7*****L     .       7*****CCCCCC****CC**'      
     -****L. .J         -**C*C**C*******C*'       
      ;**CC***;          '**CCC*****CCCC*;        
       '-****-             --**CCCCCC***-         
                               '------'           

Smoking:

                       ,L 
  --**L                C#'
 J';*P-L             ,C#" 
 P  7  7.           ,C7P  
;; J J ;;          ,C"C;  
;; C C  L          C" C   
*L 7-P ;*         ;P  #   
;CL***J**         C'  #   
'7#C*C#C'        ,P JC#C- 
 J#CCC#L      .JCCLJCC##C,
.#-   -#,     JCC#CCCCCCCC
;C.- -.*;    .CCCCCCCCCCCC
;L***J**C    ;CCCCCCCCCCCC
;*******P    'CCCCCCCCCCCP
'*******"     CCCCCCCCCCC'
 '*P-7*'      "CCCCP "--  
               '---       
wolfhammer
źródło
2

IDL 8.3, 588 597 588 bajtów

Dostaję nieco inne wartości niż ty, nie jestem pewien, dlaczego ... Zrobiłem podział liczb całkowitych na wszystko. Ale poza tym działa wspaniale ... czy te wyniki są akceptowalne? Teraz znacznie lepiej, choć z jakiegoś powodu wciąż nie jest identyczna.

pro c,m,a,b
e=2*a
f=2*b
s=size(m,/d)/[1.,e,f]
g=intarr(3,e,f)
u=floor([0:e-1]*s[1])
x=ceil([1:e]*s[1])-1
v=floor([0:f-1]*s[2])
y=ceil([1:f]*s[2])-1
n=(x-u)#(y-v)
for k=0,2 do for i=0,e-1 do for j=0,f-1 do g[k,i,f-j-1]=total(m[k,u[i]:x[i],v[j]:y[j]],/i)/n[i,j]
g=3-total(g/192,1,/i)
t=intarr(4,a,b)
for i=0,3 do t[i,*,*]=g[rebin([0:a-1]*2+i mod 2,a,b),rebin(2#[0:b-1]+i/2,a,b)]
w=total((t ne 0)*rebin(2^[0:3],4,a,b),1,/i)
for i=0,3 do w+=(w eq 2^i)*(t ge 2)[i,*,*]*(18-2^i+i/2)
w+=(w eq 15)*(total(t,1,/i)/4-1)
print,strmid(' '+"''"+'-.;/P.\;7-LJ*C#",',w[*],1),f='('+strtrim(a,2)+'A1)'
end

Przypadki testowe:

IDL> c,read_png('lemons.png'),52,25


            .-J***L-.                 .----.        
          -**********L.--          .J-*LJJ**-       
        .J****************.       J*********J.      
       ,*******************      /J**********7.     
      J********************.    ;J***********L*     
     J*********************;   .\*************/L    
    ;*********************P    ***************;*;   
   .C*********************'   ;***************;**   
   J**********************    J***************;**.  
   ***********************    ****************'**;  
   C*********************C    ********J*******;**;  
   C**********************    *******************;  
   C*********************P   ;****************7**;  
  .**********************'    ***************PJ**'  
  J*********************P     ***************\***   
 .**********************      7*************'***P   
 ;********************C"      ;************PJ**C'   
 "7******************C"        ***********PJ***;    
     '*C*************"         ;*********7J**CP     
      '*C*********CP'           7*****P\-***CP      
        -*CCCCC*P-               '7********P"       
          '---                       -----          

IDL> c,read_png('lemons.png'),70,3
        --------J**********L--------.       .-----------------        
   .J*****************************P'    -*************************;   
  ---------*************P-------         '------7**********P-----  
IDL> c,read_png('potatoes.png'),50,25





         J-"-                                     
      .J*'                     ----JL--           
     -*C*                 * -J***********-        
    J*C*L                ;****************L       
   .*C*-*              .J********************     
   J*CC;-              ********************C**CP  
   *CC#*    7         .**********************P-   
   *CCC;    '         J**********************-    
   7CCCL              **********************;     
   JCCC*.             ****C*C*****CCCC*CC***;     
  ;C*CCCL      .      ;***CC*CCCCCCCCCCCCC**      
  "--*CCC;             7***CCCCCCCCCCCCCCC*'      
     '7CC*L.  .         -*CCCCCCCCCCCCCCCP'       
       7CCCCC*'           7CC#CCCCCCC###P         
        '-7P-'             '-7CC######C-          
                                 '-'              




IDL> c,read_png('penguin.png'),26,17
                       ,L 
      ,                C# 
 "  #- ;             ,##" 
 ;  -  ;            ,#7;  
;" - - ";          ,#"J"  
;  # #  ;          #" #   
;; .-. ,;         ;;  #   
;#-***-#;         #   #   
 7#C*C#P         ,P -C#C, 
 J##-##L       JCCL-CC#CC,
,#"   "#,     JCC#CCCCCCCL
;L.- -.C;    ,CCCCCCCCCCCC
;***L***;    ;CCCCCCCCCCCC
;*******;     CCCCCCCCCCC;
 *** ***"     CCCCCC7CCCP 
 '*P--*'      "CCCCP "-"  
                --"       
sirpercival
źródło