Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Java / Java / Proyectos / Proyecto Ascii Art (metodo de Black/white)

Proyecto Ascii Art (metodo de Black/white)

Por jc mouse martes, junio 28, 2011

El Ascii Art o Arte Ascii, consiste en realizar dibujos con los caracteres ASCII (Código Americano Estándar de Intercambio de Información), y en la actualidad su uso ya es bastante conocido sobre todo en logos de compañias, blogs, foros y redes sociales como facebook utilizados como adornos.

Existen varias formas de realizar este Ascii-Art, por ejemplo:

  • Ascii Art de imagenes en Blanco y Negro
  • Acii Art de imagenes en escala de grises
  • Acii Art de los bordes de una imagen

Empezaremos por el algoritmo más sencillo, que es el Ascii Art de una imagen en blanco y negro.

¿Como funciona?

Dada una imagen en blanco y negro, se van tomando 4 pixeles de 2×2 y se van comparando de acuerdo a un patron previamente definido (Imagen 1), se toman los caracteres ASCII que se asemejen más a la forma que tienen los 4 pixeles extraidos, esto para que la imagen una vez formada, sea lo mas posible fiel a la original.

Dada una imagen en blanco y negro, se van tomando 4 pixeles de 2×2 y se van comparando de acuerdo a un patron previamente definido, se toman los caracteres ASCII que se asemejen más a la forma que tienen los 4 pixeles extraidos, esto para que la imagen una vez formada, sea lo mas posible fiel a la original.

Cada 4 pixeles leidos, corresponden a un caracter ascii y estos seran unidos a una cadena de texto, cuando se llegue al final de una columna, debe agregarse un «salto de carro» (\n) y continuarse con la siguiente hilera.

La siguiente clase i2ascii.java, resume toda la explicacion anterior. El constrcutor de la clase, lee una imagen en disco y la asigna a una clase de tipo BufferedImage, ademas la convierte en una imagen en blanco/negro utilizando un metodo que se vio en un post anterior (Imagen en blanco y Negro en Java), el metodo encargado de transformar esa imagen a Ascii-Art es ConvertToAscii() el cual devuelve en un String la imagen ya procesada.

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
 * @web http://jc-mouse.blogspot.com/
 * @author Mouse
 */
public class i2ascii {
    private int r,g,b;
    private Color color;
    private int umbral = 127;
    private int negro = -16777216;
    private int blanco = -1;
    private String ascii = "";
    // los caracteres por los que se reemplazan los pixeles    
    //                             0   1   2   3   4    5   6   7   8   9  10  11  12  13  14     15=\
    private String[] caracter =  {"`","'","°",",",".","\"","_","[","]","J","7","P","L","8","/","" + (char) 92};

    private BufferedImage foto;

    public i2ascii(){
        try {
            //se carga una foto
            foto = ImageIO.read(getClass().getResource("jcmouse.jpg"));
            //foto = ImageIO.read(getClass().getResource("jcmouse.jpg"));
            //se convierte la foto en blanco y negro
            foto = set_Blanco_y_Negro_con_Umbral(foto);

        } catch (IOException ex) {
            Logger.getLogger(i2ascii.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String ConvertToAscii(){
        BufferedImage f = foto;

        int x = f.getWidth();
        int y = f.getHeight();

        //se recorre la matriz de la imagen fila x fila de tres en tres
        for(int j=0;j<y ;j=j+3 ){
          //se recorre la matriz de la imagen col x col de dos en dos
          for(int i=0;i<x;i=i+2 ){

              if( (i < (x-1)) && (j < (y-1)) ){
              //__ 0
              //__
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==blanco ){
                  ascii = ascii + caracter[0];
                  continue;
              }
              //_X 1
              //__
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==blanco ){
                  ascii = ascii + caracter[1];
                  continue;
              }
              //X_ 2
              //__
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==blanco ){
                    ascii = ascii + caracter[2];
                    continue;
              }
              //__ 3
              //X_
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==blanco ){
                    ascii = ascii + caracter[3];
                    continue;
              }
              //__ 4
              //_X
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==negro ){
                    ascii = ascii + caracter[4];
                    continue;
              }
              //XX 5
              //__
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==blanco ){
                    ascii = ascii + caracter[5];
                    continue;
              }
              //__ 6
              //XX
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==negro ){
                    ascii = ascii + caracter[6];
                    continue;
              }
              //X_ 7
              //X_
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==blanco ){
                    ascii = ascii + caracter[7];
                    continue;
              }
              //_X 8
              //_X
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==negro ){
                  ascii = ascii + caracter[8];
                  continue;
              }
              //_X 9
              //XX
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==negro ){
                  ascii = ascii + caracter[9];
                  continue;
              }
              //XX 10
              //_X
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==negro ){
                  ascii = ascii + caracter[10];
                  continue;
              }
              //XX 11
              //X_
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==blanco ){
                  ascii = ascii + caracter[11];
                  continue;
              }
              //X_ 12
              //XX
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==negro ){
                  ascii = ascii + caracter[12];
                  continue;
              }
              //XX 13
              //XX
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==negro ){
                  ascii = ascii + caracter[13];
                  continue;
              }

              //_X 14
              //X_
              if( f.getRGB(i, j)==blanco && f.getRGB(i+1, j)==negro &&
                  f.getRGB(i, j+1)==negro && f.getRGB(i+1, j+1)==blanco ){
                  ascii = ascii + caracter[14];
                  continue;
              }

              //X_ 15
              //_X
              if( f.getRGB(i, j)==negro && f.getRGB(i+1, j)==blanco &&
                  f.getRGB(i, j+1)==blanco && f.getRGB(i+1, j+1)==negro ){
                  ascii = ascii + caracter[15];
                  continue;
              }
            }// fin si
          }
          //se concatena la fila resultante y se añade un salto de linea
          ascii = ascii + "\n";
        }        
        //se retorna la imagen transformada en ASCII
        return ascii;
    }

    //Metodo dado una imagen, la convierte en imagen en blanco y negro
    private  BufferedImage set_Blanco_y_Negro_con_Umbral(BufferedImage f){
        BufferedImage bn = new BufferedImage(f.getWidth(),f.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
        //se traspasan los colores Pixel a Pixel
        for(int i=0;i<f.getWidth();i++){
          for(int j=0;j<f.getHeight();j++){
               color = new Color(f.getRGB(i, j));
               //se extraen los valores RGB
                r = color.getRed();
                g = color.getGreen();
                b = color.getBlue();
                //dependiendo del valor del umbral, se van separando los
                // valores RGB a 0 y 255
                r =(r>umbral)? 255: 0;
                g =(g>umbral)? 255: 0;
                b =(b>umbral)? 255: 0;
                bn.setRGB(i, j, new Color(r,g,b).getRGB());
          }
        }
        return bn;
    }

}

Implementar esta clase en una interfaz, es sencilla asi que no creo que sea necesario mostrar como se hace esto. Al ser este un algoritmo simple y utlizar imagenes en blanco y negro, las imagenes resultantes, tambien seran sencillas, es por eso que es mucho mejor utilizar esta tecnica Blanco/Negro en imagenes simples como logotipos o letras.

Eso es todo

ENJOY!

Tags

Artículos similares

Tweetbotornot: Detección de Bots de Twitter

El modelo Tweetbotornot es un algoritmo de aprendizaje automático que se entrenó en miles de cuentas reales de bot y no[...]

Material Design: Notificaciones (Snackbar)

Material Design introduce una nueva forma de mostrar notificaciones al usuario, estos son los snackbar, similares a los[...]

Tink biblioteca criptográfica de Google

Tink es una biblioteca de cifrado desarrollada por un grupo de criptógrafos e ingenieros de seguridad de Google lanzado[...]

JSCRUM .:. Gestor de Proyectos

¿Qué es SCRUM? SCRUM es un modelo de referencia que define un conjunto de prácticas y roles, y que puede tomarse como pu[...]

Material Design: BottomNavigationView

BottomNavigationView es una barra de navegación que se sitúa en la parte inferior de la pantalla en los dispositivos móv[...]

JSpinner: Cambiar color de fondo y fuente

Un JSpinner es un componente swing de java con una caja de texto y un par de botones que nos permiten incrementar  y dec[...]