Main Tutorials

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

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
10 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Milad
6 years ago

Thanks.

Elad Finish
6 years ago

Do you have it for Android?

Hongten Jone
8 years ago
Telmo
10 years ago

Very Nice

Tihamer
10 years ago

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/

a??k
10 years ago

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

udaykiran
10 years ago

Good Post mkyong.

Felipe
10 years ago

It’s funny ! It works!

ninjacoder
10 years ago

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

sherbert
10 years ago
Reply to  ninjacoder

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