ASCII Art Java example

ascii-art-java

A funny Java example to create an ASCII art graphic. The concept is simple, get the image’s rgb color in “integer mode”, later, replace the color’s integer with ascii text.

P.S This example is credited for this post

ASCIIArtService.java

package com.mkyong.service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class ASCIIArtService {

    public static void main(String[] args) throws IOException {

        int width = 100;
        int height = 30;

        //BufferedImage image = ImageIO.read(new File("/Users/mkyong/Desktop/logo.jpg"));
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        g.setFont(new Font("SansSerif", Font.BOLD, 24));

        Graphics2D graphics = (Graphics2D) g;
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        graphics.drawString("JAVA", 10, 20);

        //save this image
        //ImageIO.write(image, "png", new File("/users/mkyong/ascii-art.png"));

        for (int y = 0; y < height; y++) {
            StringBuilder sb = new StringBuilder();
            for (int x = 0; x < width; x++) {

                sb.append(image.getRGB(x, y) == -16777216 ? " " : "$");

            }

            if (sb.toString().trim().isEmpty()) {
                continue;
            }

            System.out.println(sb);
        }

    }

}

Output


                  $$$        $$$$$      $$$$         $$$$     $$$$$                                 
                  $$$       $$$$$$$     $$$$         $$$$    $$$$$$$                                
                  $$$       $$$$$$$     $$$$$       $$$$$    $$$$$$$                                
                  $$$       $$$$$$$      $$$$       $$$$     $$$$$$$                                
                  $$$      $$$$ $$$$     $$$$$     $$$$$    $$$$ $$$$                               
                  $$$      $$$$ $$$$      $$$$     $$$$     $$$$ $$$$                               
                  $$$     $$$$$ $$$$$     $$$$     $$$$    $$$$$ $$$$$                              
                  $$$     $$$$   $$$$     $$$$$   $$$$$    $$$$   $$$$                              
                  $$$     $$$$   $$$$      $$$$   $$$$     $$$$   $$$$                              
                  $$$    $$$$$   $$$$$     $$$$$ $$$$$    $$$$$   $$$$$                             
                  $$$    $$$$$$$$$$$$$      $$$$ $$$$     $$$$$$$$$$$$$                             
          $$$$   $$$$    $$$$$$$$$$$$$      $$$$ $$$$     $$$$$$$$$$$$$                             
          $$$$   $$$$   $$$$$$$$$$$$$$$      $$$$$$$     $$$$$$$$$$$$$$$                            
          $$$$$ $$$$$   $$$$       $$$$      $$$$$$$     $$$$       $$$$                            
          $$$$$$$$$$$  $$$$$       $$$$$     $$$$$$$    $$$$$       $$$$$                           
           $$$$$$$$$   $$$$         $$$$      $$$$$     $$$$         $$$$                           
            $$$$$$$    $$$$         $$$$      $$$$$     $$$$         $$$$                           
What is -1677216?
The color code, in this case all colors “-1677216″ are replaced with empty ” “. This is the idea to generate the ASCII art graphic. Try load an image, and print out the rgb color, you will noticed that different color has different code.

References

  1. Wiki : ASCII Art
  2. Stackoverflow – ascii art in Java
  3. Creating a Graphic form of the Provided Integer

10 comments on “ASCII Art Java example

  1. Nice work, Mkyong.
    Here is an improved version that checks the range of brightness, splits it up into 8 ranges, and prints the corresponding character:

    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    public class AsciiArt {
    
    	public AsciiArt() {
    		//  Auto-generated constructor stub
    	}
    
    	public static void transform(ImageIcon imageIcon) {
    		int width = imageIcon.getIconWidth();
    		int height = imageIcon.getIconHeight();
    		System.out.println("wh="+width + ", " + height);
    		System.out.println("wh="+width + ", " + height);
    		Image image = imageIcon.getImage();
    
    		int dataBuffInt, sum;
    		String thisChar = "";
    		BufferedImage buffered = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
    		buffered.getGraphics().drawImage(image, 0, 0, null);
    		// Find the min/max values of the colors (i.e. lightest and darkest)
    		int min = 765;
    		int max = 0;
    		for (int y = 0; y < height; y++) {
    			for (int x = 0; x > 16) & 0xFF)+
    				//		" green="+((dataBuffInt >> 8) & 0xFF)+" blue="+((dataBuffInt >> 0) & 0xFF));
    				sum = ((dataBuffInt >> 16) & 0xFF) + ((dataBuffInt >> 8) & 0xFF) + ((dataBuffInt >> 0) & 0xFF);
    				if (sum>max) { max = sum; }
    				if (sum<min) { min = sum; }
    			}
    		}
    		
    		int range = max - min; 
    		int increment = range/8;
    		System.out.println("min="+min + ", max=" + max + ", range=" + range + ", increment=" + increment);
    		for (int y = 0; y < height; y++) {
    			StringBuilder sb = new StringBuilder();
    			for (int x = 0; x > 16) & 0xFF)+
    				//		" green="+((dataBuffInt >> 8) & 0xFF)+" blue="+((dataBuffInt >> 0) & 0xFF));
    				sum = ((dataBuffInt >> 16) & 0xFF) + ((dataBuffInt >> 8) & 0xFF) + ((dataBuffInt >> 0) & 0xFF);
    				//sb.append(buffered.getRGB(x, y) == -1 ? " " : "$");
    				// Gradient goes from space . ~ a O 8 # @   from 0 to 255*3=765
    				// Remember that 0 is black, and 765 is white. 
    				if (sum < increment+min) { thisChar = "@"; }
    				else if (sum < increment*2+min) { thisChar = "#"; }
    				else if (sum < increment*3+min) { thisChar = "8"; }
    				else if (sum < increment*4+min) { thisChar = "O"; }
    				else if (sum < increment*5+min) { thisChar = "+"; }
    				else if (sum < increment*6+min) { thisChar = "-"; }
    				else if (sum < increment*7+min) { thisChar = "."; }
    				else { thisChar = " "; }
    				sb.append(thisChar);
    			}
    
    			if (sb.toString().trim().isEmpty()) {
    				continue;
    			}
    			System.out.println(sb);
    		}
    	}
    	
    	/**
    	 * Not only loads the icon from the file, but reduces the resolution so that it will fit on a page
    	 * @param urlString
    	 * @param charactersPerLine
    	 * @return
    	 */
    	public static ImageIcon getIcon(String urlString, int charactersPerLine) {
        	System.out.println("urlString="+urlString);
        	ImageIcon icon = new ImageIcon();
    		try {
    			icon = new ImageIcon(new URL(urlString));
    			int iconWidth = icon.getIconWidth();
    			int iconHeight = icon.getIconHeight();
    			// Scale the picture so that when each pixel gets blown up to an ascii character, it still fits on a page.
    			double scaling = (double) charactersPerLine / (double) iconWidth;
    			int rows = (int) (scaling * iconHeight);
    			icon = new ImageIcon(icon.getImage().getScaledInstance(charactersPerLine, rows, java.awt.Image.SCALE_SMOOTH)); 
    		} catch (MalformedURLException e1) {
    			System.out.println("Error.  Failed to load icon "+urlString+" at "+urlString);
    			e1.printStackTrace();
    		}
        	System.out.println("icon "+icon.getIconWidth()+"x"+icon.getIconHeight());
        	return icon;
    	}
    
    	/**
    	 * We could have done the scaling in one step, but this is easier to understand.
    	 * Inefficient code that is easier to understand is more likely to be maintained and used than efficient code that is difficult to understand.
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// Prepare the frame so that you see what your original looks like (after pre-emptive stretching)
    		JFrame frame = new JFrame("Test image");
    		frame.setSize(250, 250);
    		ImageIcon icon = AsciiArt.getIcon("file:///C:/tmp/Girl.jpg", 90);
    		int height = icon.getIconHeight();
    		// Need to correct for the fact that pixels are square, but letters are rectangular
    		// If you have more (or less) space per line, the multiplier might need to be adjusted
    		height = (int)(height*0.66);
    		Image image = icon.getImage();
    		Image scaledImage = image.getScaledInstance(icon.getIconWidth(), height, Image.SCALE_DEFAULT); 
    		ImageIcon scaledIcon = new ImageIcon(scaledImage);
    		JLabel label = new JLabel("Ascii Art", scaledIcon, JLabel.CENTER);
    		frame.getContentPane().add(label);
    		frame.setVisible(true);
    		AsciiArt.transform(scaledIcon);
    	}
    
    }
    

    Result:
    urlString=file:///C:/tmp/Girl.jpg
    icon 90×124
    wh=90, 81
    wh=90, 81
    min=70, max=763, range=693, increment=86
    88OO++O+-OO+OOOOO+OOOO+++OOOO+OO88###88O88O+8888OOOOOO888#888#88O+OOO8#####O888888888OO888
    +++++OO+88+O+8##8+++O888OOOOO+OOOOO888888OOOOOOOOOOOOOO+OOO888#888OO8###8+++88888888O+OOOO
    +OO+O+++88OOO#8#O++O8888O+O+OOO+O8888OOOO++++++OOOOOO+++OO8#8O8O8888####8OO888OO8888O-OOOO
    8O88OOOO888OO##888+O8+O+++-++OO+-+++—……. ……….-++OOO8OO88#####88888++O888O+OOOO
    888OOOOO88O8####8O+8O+—–++OO+.–……. ……-+OOOO88##8888#####O+O888OOOOO+
    88OO8O88888###888++…+OOO++-………–. …..———–+OOO8O8O8######8OOO8OO888O8
    8888#8888OO8###88++..+OOO+-.. …..-… …————–+OOOO#########88OOOOOO8O88
    8O+-+OO888888+–++..++-. ….-++- ..————++———+8####888OO#88OO88OO++O
    OOO8888OOO+O–++O-++- ….-+O+. …–+++++++++–++++++++++–+—+O88888####8O8+++O+88
    8O8##8888O+O+OO+. .. ..-+O+-…—+++OOOOO+OO++-++++++++++-++–+OOOO888O+88+–+OO88
    ##8#88#888O8OO- .—–….-+OO88O888OO8O88OOO+-+++O+++++++++++O888OOO8+-+++-+OO
    ##8#8888OOOOO+ . .-. . .-O88888888OOOO888O+++++OOOOOO+++++O88OO+OO-.+O–O8O
    O8#8888O+—OO+ . …..-+O888###88888888OOO++OOOOOOO++++O++O8O++8888O8O
    8O8OO888O+–OO-. …. …..——+O8888##888888888OO++OOOOOOO+++O++O8+O8#88O8O8
    O8888O8O+++O+-. .-+++.. .–+++-++++OOO+O8888####88888888OOOO88OO8O+++OOOOOO8##8OOO
    O8888+OO+OOO+-. …-+++-…-++OO++O++OOOOOO8O88####88888O888OOO88O88+++O88888###8O-+
    ###88OO88O+–. -+.——…-+OOO888O88888OO8OOO8888##888888888OO8888O++O8##8OO888OO
    8+88888O8O+–. .++.-…—.—+O8888888#888O888OOO88#8##88888888O88O88O+OO888888O88O
    88###OOOOO–. ..-.. ..——+O8####88#888888888OO888####888888O8#888O+OOOOOOOO888
    ###8O8OOOO+-. -.- ….——+O88###8###88888888OO8888#####8888888#8#O+++++OO88888
    8OOO8888O+–. .. …. ..–+–++-+OO88###8###888888888888888#####888888###O++O88OO++–
    8O8#8888O+–…. … .–+++-O++++OO8#######8#8888888888O888#####88888###8O+OO8OO++–
    OO88###OO+O-…. -….. ..-+OOO-+OOO++OOO8#######88888888888OO888#######888###8O++OOO+O++
    O8+88##O8+O..-.. .-…….-++OO+-+OOO++OO888#######8888888888OOO888###@###88#@@#O+++OOOO++
    8#888OO8+O-..-…—-..—-+OOOO-OO8OOOOO888#######888888888888OOO888###@#####@@8++OOO8888
    8###8O+-8O-.-….———+OOOOO+OOOOOOOO8##8#######88888OO888888OO888##@@@###@@#O++OO88OO
    88##88O+8+-.-…-+——+++OOOOO+OOOO8OOOO8##########88888OO888888O8888#@@@@@#@@@8O+OO88OO
    888O+O+O+–.-..-++-.—–+++OOO+OOOO8888OO8###########88888OOO8888888888##@@@@@@@#O+OO+O8O
    888O+OOO+-.–.–O+-..—++++OOO+OOOO8888OO8###########888888OOO888888888##@@@@@@@#OO+O+++-
    8OOO8O8O+——+OO-..—++++OOO+OOO888888888###########888888OOOO8888888###@@@@@@@8O++OO88
    OO888+OO——-+OO-..—+–+OOO+OOO8888888888###########888888OOOOO88888####@@@@@@#OOOO888
    88+OOOOO——-OOO…….–+OOOOOOO8888OO888888#########888OOOOOOOOOO8888##@@@##@@#OO++O88
    8O+OO8OO——+OO+.. ..–+OOOOOO8888OO88888888888#####888OOOOOOOOOOO888#######@@#8O++OOO
    O88OOOO++—–+O+-. ..-+OOOO888888OOO88888888888888888888888OOOOOOOOOOOO88####@@@@#8OOOOOO
    88#O+OO——-+O+- .-++OO88888888O+O888888888888888888888888OOOO++++OOOO88###@@@@@#8OOOOO+
    ##8OO+++—–+O8O+.-+O88####88OOOOOO88888888888#########8##88OOOO++++OOOO8##@@@@###8OOOOO+
    ##OOO++——+O8OO-+O88#####8O8OO8OOO888OOO888#####@@@@@#8888OOOO+++OOOOO8##@@@####8OOO88-
    88OOO+++—–+OOOOOO+O+O8##888###8OOO88OOOO88###@##@@@@@####888OOOO+OOOOO8#@@@@####88OOO8O
    88OOOO+——+OOOO++-.+O8##88###88OOO888OO888##@###@@@@#888OOOOOO++++OOO88##@@@####88OOO8O
    888O8O——-+OOOO+- .-++O88####88OOOO8OOOO888#####88888OOOOOOOO+++++OOO8##@@@######8OOOO8
    88888O-+—–+OOO+- -+O8888#888O+++OOOOOOOO888####88888888OOOO+++OOOOO8@######8###8O+++O
    88O#8+++—–OOOO+. -+O888888OO++++OOOOOOOOO8888###8888888OOOO+++OOOOO#@######8###8OOOOO
    8OO8O++++—+O888+. ..—-++OO+—..+OOOOOOOOOO888888888888OOOOO++OOOO8#######88##8OO88OO
    O888O++++—+O888+. ..——–+-… -OOOOOOOOOO88888888888OOOOOOOOOOOO8#######8###8OO8OOO
    888OO++++—OO888O- ….–++++–.. .+OO++OOOO8888888888OOOOOOOOOOOOO88###########8++++-O
    888OOO+++—OO888O- …-+OOOO++. .+++++OOOO888888888OOOOOOOOOOOOOO8############OOOO+O8
    O+OO+++++–+OO8888+. ..-+OOOOOO+ .+OOOO++O+OO88888888OOOOOOOOOOOOOO#@@@@@@@@###8O888OOO
    O+OO+++++–+OOO888O…–+OO8888+ .-+OOOOOOOOOO88888888OOOOOOOOOOOOO8@@@@@@@@####8O8888OO
    +-OO+.++—+OO8O888O..-+OO88888OOOOOOOOOOO888OOO888888888OOOOOOOOOOOO#@@@@@@@@###8O88O888O
    O+O+O-+++–+OO8O88#8-.-+OOO8888OOOOOOOOOOOOOOOOO88888888888OOOOOOOOOO#@@@@@@@@@##OO8#OO888
    ++–+++++–+OO8OO8888–+OO8888OOOOOOO888888OOOOOOOO888888888OOOOOOOO#@@@@@@@@@##OOO+++-O88
    +—+O+++–+OO88O88##+-+OOO888OOOOOOO888888OOOOOOOO88####888OOOOOOO8#@@@@@@@@##8O++++O+O88
    +—-++++–++O88888##8O+OOO8888#88888888888888888#@@@####888OOOOOO8###########8O+-++OO88O8
    ++++—O+–++O88888###8++OO8888##@##88###888#8###@@##8###888OOOOO88##########8OOO-+OOOO888
    +-++O++++–++OO8O88####8OOOO88888888#############888888#888888888##88888####8OOOO+OOOOOOO-
    +++++++++–++OO8O+8#####8OOOO8888O8888#######8888888888888888888##888888###88OOOO88OOO+-+.
    O++++++++-+++OOO.+8#####@#8OOOOOOOOOO88888888888OOO88888888888###888888###88OO8OOO88OO++++
    +-+O–++–++++O-.+88###@@@@@8OOOOOOOOO8888888888888OOO888#######88888####8O88888OOOOOO++++
    8+++–+++-++++O-.+8####@@@@@#8OOOOOO888888888888888OO888###@@##88888####888##88O8OOO8OOO++
    8888OO++—+-+O+++8#88##@@@##888OOOOOOO88888888888OO8##@@@@@###888####8888888OOOOOO+O++++O
    88OOO++——+OO+-O888##@@##O8888OOOOOO8888888888888#@@@@#@@###888####888OOOOOOOOOO++—-+
    O+OOOO++——+++-O888##@@@@#8888#88OOO88888888888#@@@@@@@@#########8888#88OOOO8OOOOO-++++
    OOOOOO++——–++O8888#@@#O###88###888888888888#@@@@@#@@@#########888OO8888O++OOOOO+—++
    O8OO+++——-..++OOOO8##88#@@#88#####888888##@@@@@@@#@@@#########88888OOOOOOO+++O+OOO888+
    OOO+O++——-..O+OOOO88###@@@@88######88888###@@@@@@@@@@########888888OOOOOOO+++O++OO8888
    -+OO+++–.—..-O++OO+88##@@@@@#8######8888O8###@@@@@@@@###8#####88OOOO8OOOOOOO+++O++OOOOO
    +88OOO+-.—+..+O++OOO88#@@@@@@#8#######88O.+8##@@@@@@@###88###888OOOOOOOOO+++++++O++OOO8O
    +O88O+-.—+..-++++OOO8###@@@@#88######888++O88#@@@@@###888###88888O88OOOOOO+++++++++++OOO
    O888+———-++O++OO88##@@@@#88######888OOO8###@@####8888##8888888OOOOOOOO++++++++++++OO
    ++OO+–.——-+++++O888###@@8OOO####88OOOOO###8##8O888888#88888O8OOOO+++++++++++-+++++-+O
    +++++—+——++O++O888###@#8O+O8#8OOO++OO88#O8#8O-+88OO8#88888OOOOO++++++++++——++–+
    +O+++——-++-+++-+O888##@#O+O++O+OO–+888888+O8OO+OOOO88###8OOOOO+OO++++++++++——-++-
    O+++——–O+-+++–O888#@@#OOO+OOO8+.-O8888#OO88O++O+OO88##88OOOOO+++++++++++++—+—-+-
    ++-++——+O+-++-.+OO888##8O+++++O-OO88O88###8O+—+-+8###8OOO++++++++++++++++++++——+
    ++++——-+O+-++–+OOOO+O8OOO+-+88O88#8O88#8O—-++-++##8888O——-+++++++++++++++++—-
    +++——-+OO+–+–+OOO+O88OO8++O8O8O8#8O888++.–+-+–+888O+O8O-……-++++O+++++++++++—
    ++++–+—+OO+—+++OOO+88+–+-OO8O++88OOO8+-…-+ -. .–..+- -+-……—++O+++++++++++++
    ++++–+—OO++—+++OO+O88+-O++OOO+++88OOOO+-…++ .. … .+..+O+..–….–++++++++++++++
    OO+—+–++O++–+++OOO-OO+++O++++++-OOOO+O-…-++- .. .+– .+.-8O—–……+O++++++++++
    O++–+++-++O++–+++OOO-OO+++O+++++++OO+++-….-++- .. .–. -++-OO..-…..—+OO++++++++
    +++–+—O+O++–++++++++O+++OO+O+O+O+++.. .. .-++- . ..-. .O–88–.-+OO88888O8O++++++

    https://sites.google.com/site/smelltheoxygen/

    Reply
  2. I think you are Crazy Clever Big Programmer..:)God Bless You..

    Reply
  3. (facepalm) Could you please work on some interest projects?

    Reply
    1. dude, give the guy a break! he gives you GOLD all the time!!!

      Reply

Leave a Comment

Your email address will not be published. Required fields are marked *