ASCII Art Generation


13

Завдання

Напишіть програму або функцію, яка приймає зображення ширини wта висоти h, двох цілих чисел a <= w/2і b <= h/2та виводить зображення ascii art із розмірами ax b.

Мистецтво ascii має генеруватися за допомогою наступних кроків (або іншого процесу з тим же результатом):

  1. Змініть розмір wx hна 2ax 2b. Колір пікселя (x, y)на зміненому зображенні повинен дорівнювати середньому кольорам усіх пікселів від вихідного зображення всередині прямокутника з такими кутами:

    (floor[x * w/2a], floor[y * h/2b])
    (ceil[(x+1) * w/2a], ceil[(y+1) * h/2b])
    
  2. Зменшене зображення слід знежирити, взявши середнє значення червоного, зеленого та синього компонентів кольору та встановивши кожен компонент до цього середнього.

  3. Символ повинен бути виведений для кожного блоку пікселів 2x2, дотримуючись наведених нижче правил:

    • Нехай e = 3 - floor[color/64], де колір позначає червону складову кольору верхнього лівого пікселя (в діапазоні 0..255). Нехай f, gі hпосилається на це значення, але для верхнього правого, нижнього лівого та нижнього правого пікселів відповідно.
    • Нехай zбуде в середньому e, f, g, h.
    • Виведіть символ, відповідний наступному (білий зображує піксель, де 3 - floor[color/64]дорівнює нулю, а сірий - ненульовий).
    • Усі пікселі дорівнюють нулю= Виведіть пробіл ( )
    • Лівий верхній піксель не має нуляабо Правий верхній піксель не є нульовим= вихід , "якщо e (or f) >= 2і в 'іншому випадку.
    • Нижній лівий піксель не є нульовимабо Правий нижній піксель не є нульовим= вихід , ,якщо g (or h) >= 2і в .іншому випадку.
    • Верхні пікселі не нульовіабо Нижні пікселі ненульові= вихід-
    • Залишилося пікселів ненульовимабо Праві пікселі не нульові= вихід;
    • Лівий верхній, нижній правий пікселі ненульовий = Вихід \
    • Правий верхній, нижній лівий пікселі ненульовий = Вихід /
    • Лівий верхній нульовий піксель = Вихід J
    • Правий верхній нульовий піксель = Вихід L
    • Нижній лівий піксельний нуль = Вихід 7
    • Правий нижній піксельний нуль = Вихід P
    • Усі ненульові
      • z = 1: вихід *.
      • z = 2: вихід C.
      • z = 3: вихід #.

Інші зауваження: У всіх середніх значеннях, наведених у наведених вище кроках, слід використовувати ціле ділення (тобто округлення до 0).

Ви можете використовувати бібліотеку для читання зображень, але бібліотеки можуть не використовуватися для етапів зміни розміру та перенасичення.

Вхідні дані

Ваша програма буде містити три дані:

  • Зображення. Це зображення може бути у будь-якому обраному вами форматі (наприклад, PNG, PPM)
  • Ширина мистецтва ascii (у кількості символів)
  • Висота мистецтва ascii (у кількості символів)

Вхід може бути прочитаний через STDIN, переданий як аргумент командного рядка, збережений у вигляді змінної тощо.

Вихідні дані

Ваша програма виведе мистецтво ascii, що генерується із зображення та за допомогою описаного вище процесу. Кожен рядок повинен мати однакову ширину (ширина, передана як вхідний), і жодних зайвих пробілів не можна додавати чи видаляти. В останньому рядку може бути наступний новий рядок, але це не є обов’язковим. Пусті лінії (рядки з пробілами) не повинні опускатися.

Приклади

Усі зображення були взяті з Вікіпедії та оприлюднені у відкритому доступі. Очікується, що ваша програма працюватиме для всіх зображень та дійсних даних.

Зображення лимонів

Ширина = 52, висота = 25:


            .-- *** - ----.        
          - ********** L .-- .-- 7 ---- P-       
        .J ****************. . ********* \.      
       , ****************** L \ J ********** '.     
      - ********************. J *********** L /     
     J *********************; ./*************.L    
    ; ********************* 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      
        - * CCCCC * P- '7 ******** P'       
          '---' --- '          

Ширина: 70, Висота: 3:

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

Картопля

Ширина: 50, Висота: 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 ** CCCC **      
  "7 ***** L. 7 ***** CCCCCC **** CC **"      
     - *****. -J - ** C * C * CC ****** CC * '       
      ; ** CC ***; '** CCC ***** CCCC *;        
       '- **** - - *** CCCCC *** -         
                               '------'           




Зразок кліпарт

Ширина: 26, Висота: 17:

    -, Л 
  J - ** L .C # 
 J '; * PL, C # " 
.PP 7. JC7P  
;; * J ;; , C'C;  
J; CC; L C "#   
* L 7-P; *; ПК   
7CL *** J * ПК '#   
'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" -  
               '---       

Це , тому найкоротша відповідь виграє.


2
ось тихі каліки .... ....
15:55

Коли ви говорите введення зображення, ви маєте на увазі ім'я файлу? Або фактичні дані зображення?
sirpercival

@sirpercival або добре
es1024

Відповіді:


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
}

Приклади:

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

Лимони:

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

Шпони:

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

Смокінг:

                       ,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 байт

Я отримую трохи інші значення, ніж ви, я не знаю, чому ... Я зробив ціле поділ для всього. Але інакше це чудово працює ... чи прийнятні ці результати? Набагато краще зараз, хоча все ще не однаково чомусь.

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

Тестові приклади:

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 "-"  
                --"       
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.