Musings about Java and Swing

ASCII Art

Years ago, when the only computers around were the mainframes used by large businesses, one of the ways that programmers fooled around was to create Ascii art.

Basically, take a picture, convert it to grey scale, and use different characters to represent the level of whiteness (or blackness) in the picture.

Years ago, this process was done by hand. Now, we can do it with a simple Java program of less than 100 lines.

Here’s the photograph I started with.

A woman

And here’s the Ascii art my program generated.

..,........................................,,..,............
................................,......,......,.............
..........................,................:,.:,,:..........
..............................................,,........,...
...................................:,..........:.,,.,,....,.
.,.,,,..,,.................,:---===:-===:......,,...,,...,,.
...,,..,,.,...,...........,,::--=++=-+++#=-....,......,...,,
....,,:,,,,..,...........,,,:,.+-:::-=%#+++=:...............
.,...::--:,,,,,,....,...,:,-:,=-:,,:::=##+++-...............
:::.:,::,.:::,.,,,..:,.,-:,,#=--+#+-:-+#%%==#=,.............
::,..,:==-:--::,::,..,.=+::#+#%+#+=..-%%%%%+++:.............
::,..-=,,.:.-=::,:,,,.:=+-#=,.+,,,,..,-+++%%+==,............
:,,,--:--:..,,,,==-,,,,=#+%,...,::..,:,--=+%%+=:-..:........
-:,:---==-:::,,,:-::,,:+#+#....:,..,:,,:-=@%%%#,:-:-::......
:=-:,:=--.:--,,-:::-.,%%=@=+...,..:---::-+@%%%%,-::.........
---:,:,:-===-::::-=:,:#%=%=%==....,:,,,:@@@@%%##:,..........
---:::--:--==---:-:.=-%#=#=#%#%+#++==%%@%@%@%%#%#-:.........
,:::,,..,..,...,::,.,+%+=+=#%%%%#%%%#%%%%%%%@%#%#:#:........
.................,-.==#=:==#%#%######%@@@%@%%%%%#+.,:.......
...........,,:,---+,=+#=-%%+###%####%@@@@%@%@%%%%+=.........
.........,,:-====+-#=#++--++=+++++++##%@@@%%%%%%%+=:,.......
.......,.:-===+==+==:+#%-++=++++====+=+#%%%%%%%#%#+-........
......,-:--+=#==+++==:=+:++#%++========++#%%#%%#+++-........
.....,,-++##=%=#+-:-:=:-=#=+###+=====++=+=##%+%%+=-:,......:
,,..,::-==##+@#%:#@=--:+-:#%#%#%++=========#%%###+=-,,.,,-:=
:.,.,:-+##+#%%%=+:==--:==:%#%%%%=+====-=====#%%==-:-:-:,::::
.,,.,:#-++#%%@#=::::-::-:++%##%#%+==========+%#+=.-,-:,:-:-=
:-,,:-==+#%%@%+--,:::,:--==+###+==+++++====+###==-:----=,-,:
::,,::=++#%@@#--:,,,:+:---+++=++++###+++#+=+==,:=+===#+#::==
=:.,:++##%%%%=-:-==-:+==+##+#+++##+++++%#++=-=,--======##:::
:-.,-:=#%%%=++---:--==+##%#%%%%%%%%%%##%%,-%:::=:-=:.:#-:+=+
-..++=+#%%@::#-::=:=##+-==@%%%%%##%%#+--%,-=--+--%+::,+%%:--
=.,:###%%@%--%-:----==+++=-=-=++%#+====--#%=-=#:@=++:#=+-++=
-,%%##%%@@=-=:-::-@%=---++++=+=---=====-+::-++::-#+-=%++---%
=.+######--=-:+-,::-=##+=+-=====+==++==-:==--==,#-+=#++%--+=
+...,:--=--%++::,:::--++++=-++===+=+=##+#-====.,==-+%@@##=@=
-...,::-=---=-=,:::-:::-:+--===+=-==-=+==-=++%++#=+-%+%++=-+
:...,,::-=====-,,::::::=--=-=-=+=++=====-=--#@+-#%:-#%-=+-##

Quite a difference. Stand as far back from the screen as you can to make out the woman.

Anyway, here’s the code. My program reads the image, converts the colors to a grey scale, and picks an Ascii character to represent the grey level.

The program also reduces the number of Ascii characters to a reasonable level.

package com.ggl.testing;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageToAscii implements Runnable {

	public static void main(String[] args) {
		new ImageToAscii(args[0]).run();
	}

	private static final String ASCII_CHARACTERS = "@%#+=-:,.";

	private String fileName;

	public ImageToAscii(String fileName) {
		this.fileName = fileName;
	}

	@Override
	public void run() {
		BufferedImage image = readImage();
		if (image == null) {
			return;
		}

		StringBuilder builder = new StringBuilder();

		for (int y = 0; y < image.getHeight(); y += 24) {
			for (int x = 0; x < image.getWidth(); x += 10) {
				int index = getAsciiCharacterPosition(image, x, y);
				builder.append(ASCII_CHARACTERS.charAt(index));
			}
			builder.append("\n");
		}

		System.out.println(builder.toString());
	}

	private int getAsciiCharacterPosition(BufferedImage image, int x, int y) {
		int pixel = image.getRGB(x, y);
		Color color = new Color(pixel, true);
		double red = 0.2989D * color.getRed();
		double green = 0.5870D * color.getGreen();
		double blue = 0.1140D * color.getBlue();
		int sum = (int) Math.round(red + green + blue);
		return Math.min(sum / 25, ASCII_CHARACTERS.length() - 1);
	}

	private BufferedImage readImage() {
		try {
			return ImageIO.read(new File(fileName));
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

}

Post a Comment

Your email is kept private. Required fields are marked *