Geração de Arte ASCII


13

Tarefa

Escreva um programa ou função que tire uma imagem de largura we altura h, e dois números inteiros a <= w/2e b <= h/2, e produza uma representação artística da imagem, com as dimensões ax b.

A arte ascii deve ser gerada através das seguintes etapas (ou outro processo com a mesma saída):

  1. Redimensionar o wx hpara 2ax 2b. A cor do pixel (x, y)na imagem redimensionada deve ser igual à média das cores de todos os pixels da imagem original dentro do retângulo com os seguintes cantos:

    (floor[x * w/2a], floor[y * h/2b])
    (ceil[(x+1) * w/2a], ceil[(y+1) * h/2b])
    
  2. A imagem redimensionada deve ser dessaturada tomando a média dos componentes vermelho, verde e azul da cor e definindo cada componente para essa média.

  3. Um caractere deve ser emitido para cada bloco 2x2 de pixels, seguindo as regras abaixo:

    • Deixe e = 3 - floor[color/64], onde cor se refere ao componente vermelho da cor do pixel superior esquerdo (no intervalo de 0 a 255). Vamos f, ge hreferem-se a este valor, mas para o canto superior direito, canto inferior esquerdo, e pixels inferior direito, respectivamente.
    • Vamos zser a média de e, f, g, h.
    • Emita o caractere correspondente ao seguinte (branco representa um pixel onde 3 - floor[color/64]é zero e cinza representa diferente de zero).
    • Todos os pixels são zero= Saída de espaço ( )
    • O pixel superior esquerdo é diferente de zeroou O pixel superior direito é diferente de zero= Saída "se e (or f) >= 2e 'caso contrário.
    • O pixel inferior esquerdo é diferente de zeroou O pixel inferior direito é diferente de zero= Saída ,se g (or h) >= 2e .caso contrário.
    • Pixels principais diferentes de zeroou Pixels inferiores diferentes de zero= Saída-
    • Pixels esquerdos diferentes de zeroou Pixels à direita diferentes de zero= Saída;
    • Pixels superior esquerdo e inferior direito diferentes de zero = Saída \
    • Pixels superior direito e inferior esquerdo diferentes de zero = Saída /
    • Pixel superior esquerdo zero = Saída J
    • Pixel superior direito zero = Saída L
    • Pixel inferior esquerdo zero = Saída 7
    • Pixel inferior direito zero = Saída P
    • Tudo diferente de zero
      • z = 1: saída *.
      • z = 2: saída C.
      • z = 3: saída #.

Outras notas: Todas as médias tomadas nas etapas acima devem usar a divisão inteira (ou seja, arredondar para 0).

Você pode usar uma biblioteca para ler imagens, mas as bibliotecas não podem ser usadas para as etapas de redimensionamento e dessaturação.

Entrada

Seu programa coletará três dados:

  • Uma imagem. Esta imagem pode estar em qualquer formato de sua escolha (por exemplo, PNG, PPM)
  • A largura da arte ascii (em número de caracteres)
  • A altura da arte ascii (em número de caracteres)

A entrada pode ser lida através de STDIN, passada como um argumento de linha de comando, armazenada como uma variável, etc.

Resultado

Seu programa exibirá a arte ascii gerada a partir da imagem e através do processo descrito acima. Cada linha deve ter a mesma largura (a largura passada como entrada) e nenhum espaço extra pode ser adicionado ou removido. A última linha pode ter uma nova linha à direita, mas isso não é obrigatório. Linhas em branco (linhas apenas com espaços) não devem ser omitidas.

Exemplos

Todas as imagens foram tiradas da Wikipedia e lançadas em domínio público. Espera-se que seu programa funcione para todas as imagens e entradas válidas.

Imagem de limões

Largura = 52, Altura = 25:


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

Largura: 70, Altura: 3:

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

Batatas

Largura: 50, Altura: 25:





        .J ---                                     
      .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 ** CC0 **      
  "7 ***** L. 7 ***** CCCCCC **** CC ** '      
     - *****. -J - ** C * C * CC ****** CC * '       
      ; ** CC ***; '** CCC ***** ATCC *;        
       «- **** - - *** SHIPC *** -         
                               '------'           




Amostra de clipart

Largura: 26, Altura: 17:

    - ,EU 
  J - ** L .C # 
 J '; * PL, C # " 
.PP 7. JC7P  
;; * J ;; C'C;  
J; 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 *' "CC0P" -  
               '---       

Isso é , então a resposta mais curta vence.


2
isso é desafio paralisante silencioso .... ...
Abr001am 04/04

Quando você diz entrada de imagem, você quer dizer um nome de arquivo? Ou os dados da imagem real?
Sirpercival 5/05

@sirpercival quer é bom
es1024

Respostas:


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
}

Exemplos:

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

Limões:

            .--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***-         
                               '------'           

Tux:

                       ,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 "--  
               '---       

2

IDL 8,3, 588 597 588 bytes

Estou recebendo valores um pouco diferentes do que você, não sei por que ... fiz divisão inteira para tudo. Mas, de outra forma, funciona esplendidamente ... esses resultados são aceitáveis? Muito melhor agora, embora ainda não seja idêntico por algum motivo.

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

Casos de teste:

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 "-"  
                --"       
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.