ASCII Art Generator Library in Java

ASCII art is a method of creating pictures using the normal printable characters used in computers (ASCII character set). ASCII art can be composed using normal text editors. However this process is very cumbersome. There are a number of software packages available that can convert images or text to ASCII art.

If you are looking for a programmatic ASCII art generator in Java just for text, check out the following Java program. This program can create ASCII art of any text using a number of fonts and in different sizes. You can also choose the symbol used for your ASCII art.

Download Source Code - ASCII Art Generator in Java

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

/**
 * ASCII Art Generator in Java. 
 * Prints a given text as an ASCII text art on the console. 
 * This code is licensed under - CC Attribution CC BY 4.0.
 * @author www.quickprogrammingtips.com
 *
 */
public class ASCIIArtGenerator {
    
    public static final int ART_SIZE_SMALL = 12;
    public static final int ART_SIZE_MEDIUM = 18;
    public static final int ART_SIZE_LARGE = 24;
    public static final int ART_SIZE_HUGE = 32;

    private static final String DEFAULT_ART_SYMBOL = "*";

    public enum ASCIIArtFont {
        ART_FONT_DIALOG("Dialog"), ART_FONT_DIALOG_INPUT("DialogInput"), 
        ART_FONT_MONO("Monospaced"),ART_FONT_SERIF("Serif"), ART_FONT_SANS_SERIF("SansSerif");

        private String value;

        public String getValue() {
            return value;
        }

        private ASCIIArtFont(String value) {
            this.value = value;
        }
    }

    public static void main(String[] args) throws Exception {
        ASCIIArtGenerator artGen = new ASCIIArtGenerator();
        
        System.out.println();
        artGen.printTextArt("Hello", ASCIIArtGenerator.ART_SIZE_MEDIUM);
        System.out.println();
        
        System.out.println();
        artGen.printTextArt("Love is life!", ASCIIArtGenerator.ART_SIZE_SMALL, ASCIIArtFont.ART_FONT_MONO,"@");
        System.out.println();
        
    }

    /**
     * Prints ASCII art for the specified text. For size, you can use predefined sizes or a custom size.
     * Usage - printTextArt("Hi",30,ASCIIArtFont.ART_FONT_SERIF,"@");
     * @param artText
     * @param textHeight - Use a predefined size or a custom type
     * @param fontType - Use one of the available fonts
     * @param artSymbol - Specify the character for printing the ascii art
     * @throws Exception
     */
    private void printTextArt(String artText, int textHeight, ASCIIArtFont fontType, String artSymbol) throws Exception {
        String fontName = fontType.getValue();
        int imageWidth = findImageWidth(textHeight, artText, fontName);

        BufferedImage image = new BufferedImage(imageWidth, textHeight, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        Font font = new Font(fontName, Font.BOLD, textHeight);
        g.setFont(font);

        Graphics2D graphics = (Graphics2D) g;
        graphics.drawString(artText, 0, getBaselinePosition(g, font));

        for (int y = 0; y < textHeight; y++) {
            StringBuilder sb = new StringBuilder();
            for (int x = 0; x < imageWidth; x++)
                sb.append(image.getRGB(x, y) == Color.WHITE.getRGB() ? artSymbol : " ");
            if (sb.toString().trim().isEmpty())
                continue;
            System.out.println(sb);
        }
    }

    /**
     * Convenience method for printing ascii text art.
     * Font default - Dialog,  Art symbol default - *
     * @param artText
     * @param textHeight
     * @throws Exception
     */
    private void printTextArt(String artText, int textHeight) throws Exception {
        printTextArt(artText, textHeight, ASCIIArtFont.ART_FONT_DIALOG, DEFAULT_ART_SYMBOL);
    }

    /**
     * Using the Current font and current art text find the width of the full image
     * @param textHeight
     * @param artText
     * @param fontName
     * @return
     */
    private int findImageWidth(int textHeight, String artText, String fontName) {
        BufferedImage im = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
        Graphics g = im.getGraphics();
        g.setFont(new Font(fontName, Font.BOLD, textHeight));
        return g.getFontMetrics().stringWidth(artText);
    }

    /**
     * Find where the text baseline should be drawn so that the characters are within image
     * @param g
     * @param font
     * @return
     */
    private int getBaselinePosition(Graphics g, Font font) {
        FontMetrics metrics = g.getFontMetrics(font);
        int y = metrics.getAscent() - metrics.getDescent();
        return y;
    }
}

How ASCII Art Generator for Java Works?

ASCII art generator library for Java uses image drawing and image pixel detection to draw ASCII art. The algorithm for art generator is,

  • Using the selected font properties and ascii art size, calculate the width of the image required for printing the art text.
  • Using font properties, find the baseline position where the text should be drawn. This ensures that the drawn image is vertically centered.
  • Using Java awt API, draw the image corresponding to the art text. The image is drawn in white on a black background.
  • Iterate through the pixels of the image from top to bottom. Whenever a white pixel is detected, we add the art symbol otherwise we add a space.
  • Each row of pixels are then printed as a single line on the console. Voila! you now have the ascii art ready.

ASCII Art in Java - Samples

Following are some of the ASCII text art generated by the program,

artGen.printTextArt("Help", ASCIIArtGenerator.ART_SIZE_MEDIUM);
                          ***              
 ***     ***              ***              
 ***     ***              ***              
 ***     ***              ***              
 ***     ***     *****    ***   *** ***    
 ***     ***    *******   ***   ********   
 ***********   ****  ***  ***   **** ****  
 ***********   ***   ***  ***   ***   ***  
 ***     ***   *********  ***   ***   ***  
 ***     ***   *********  ***   ***   ***  
 ***     ***   ***        ***   ***   ***  
 ***     ***   ****       ***   ****  ***  
 ***     ***    ********  ***   ********   
 ***     ***     *******  ***   *** ***    
                                ***        
                                ***        
                                ***       

 

artGen.printTextArt("Java", 14,ASCIIArtFont.ART_FONT_DIALOG,"+");
  ++                          
  ++                          
  ++                          
  ++    ++++  ++     +  ++++  
  ++   +   ++  ++   +  +   ++ 
  ++       ++  ++   +      ++ 
  ++    +++++   ++ +    +++++ 
  ++   ++  ++   ++ +   ++  ++ 
  ++   ++  ++    ++    ++  ++ 
  ++    ++++++   ++     ++++++
  ++                          
+++                         

The ASCII art generator source code is licensed under Creative Commons Attribution. You can use the source code for anything as long as attribution link is given.

How to Swap Two Numbers in Java

Swapping two number is easy when you use a temporary variable. The following Java programs swaps two numbers using a temporary variable of the same type.

// Java program to swap numbers using temporary variable
public class SwapNumbersWithTemp {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("a="+a+",b="+b);

        int temp = a;
        a = b;
        b = temp;
        
        System.out.println("a="+a+",b="+b);
    }
}

The following program swaps two numbers without using a temporary variable. It uses addition and subtraction to move values around.

// Example: Java program to swap numbers without temp variable
public class SwapNumbersWithoutTemp {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("a="+a+",b="+b);

        a = a + b; // a is now a+b
        b = a - b; // b is now a
        a = a - b; // a is now b
        
        System.out.println("a="+a+",b="+b);
    }
}

The following program swaps numbers using a function without explicit temporary variables. This example works because the value of the b actually creates an implicit temporary variable during the method invocation.

// Swap numbers without temporary variable - Java example
public class SwapNumberWithFunction {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("a=" + a + ",b=" + b);

        a = getB(b,b=a);

        System.out.println("a=" + a + ",b=" + b);
    }
    
    public static int getB(int b,int a) {
        return b;
    }
}

How to List Files in a Directory Using Files.list

Java 8 introduced a number of utility classes intended to improve programmer productivity. The java.nio package was enhanced with a number of new methods. This article explores the list method in java.nio.file.Files class. This new method returns all the entries (files and directories) in the specified directory. However it is not recursive (for recursive use case there is another method named walk). Also note that the entries are loaded lazily for performance reasons.

How to List Files in a Directory Using Java 8 Features

The following example Java program uses Files.list method and has the following functions,

  • printlAllFiles - Prints all file names in the specified folder
  • printAllFilesInUpperCase - Prints all file names in upper case. This method illustrates the use of lambdas in Java 8.
  • printAllHiddenFiles - Prints all hidden file names in the specified folder. This method illustrates the use of filter function over the list function. Some of the other boolean functions available in Files class are isDirectory, isExecutable, isReadable, isRegularFile, isSymbolicLink and isWritable.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ListFilesInDirectory {

    public static void main(String[] args) throws Exception {
        // For windows replace with your folder
        // Example - c:\\jj.
        String rootFolder = "/Users/jj";
        printlAllFiles(rootFolder);
        printAllFilesInUpperCase(rootFolder);
        printAllHiddenFiles(rootFolder);
    }

    // Print all file names in the specified folder
    // Includes directories and hidden files
    // Nested sub-directories are not listed
    private static void printlAllFiles(String rootFolder) throws Exception {
        Files.list(Paths.get(rootFolder)).forEach(System.out::println);
    }

    // Print all file names in the specified folder in upper case
    private static void printAllFilesInUpperCase(String rootFolder) throws Exception {
        Files.list(Paths.get(rootFolder)).forEach(path -> {
            System.out.println(path.toString().toUpperCase());
        });
    }

    // Print all names of all hidden files in specified folder
    private static void printAllHiddenFiles(String rootFolder) throws Exception {
        Files.list(Paths.get(rootFolder)).filter(t -> {
            try {
                return Files.isHidden(t);
            } catch (IOException e) {
                return false;
            }
        }).forEach(System.out::println);
    }
}

 

References

How to Get the List of Running Processes in Mac Using Java

In a Mac machine, the list of all running processes can be retrieved using the following command in the console. The option -e displays all processes including processes owned by other users. The -o command flag instructs ps to show only the command name (with arguments). To get the command name without arguments, use comm instead of command.

ps -e -o command

How to List All Running Processes in Mac Using Java

Java API has a class called Runtime which can be used to run operating system commands such as ps in Mac.  The following sample program in Java demonstrates the use of Runtime class to get a list of running processes from the Mac machine.

import java.io.BufferedReader;
import java.io.InputStreamReader;

// Displays all running processes in a Mac machine.
public class ShowProcessesInMac {

    public static void main(String[] args) throws Exception {
        printAllProcesses();
    }
    // Java example program to display the names of all running mac processes
    private static void printAllProcesses() throws Exception{
        // -e - show all processes including processes of other users
        // -o command - restrict the output to just the process name
        Process process = Runtime.getRuntime().exec("ps -e -o command");
        BufferedReader r =  new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        
        while((line=r.readLine())!=null) {
            System.out.println(line);
        }
    }
}

You can use the variations of the ps command to get different types of data regarding running processes.

ps -er -o %cpu,command

The above command displays all processes sorted in the descending order of cpu percentage. The columns displayed are %cpu and the process command including the command arguments.

ps -em -o %mem,command

The above command displays all processes sorted in the descending order of memory percentage. The columns displayed are %memory usage in percentage and the process command including the command arguments.

The following sample Java program shows how one of the variations above can be used to print the Mac process with the highest CPU usage. This program extracts the CPU usage and the name of the process (including process arguments) with highest CPU usage. It is quite possible that this program itself may be reported as the top CPU process!

import java.io.BufferedReader;
import java.io.InputStreamReader;

// Sample Java program to print highest CPU process in a Mac machine
// Note that this program itself may be reported as the top process!
public class TopCPUMacProcess {

    public static void main(String[] args) throws Exception {
        printProcessWithHighestCPU();
    }

    // Java example program to print the name of the process with highest CPU usage in mac
    private static void printProcessWithHighestCPU() throws Exception {
        Process process = Runtime.getRuntime().exec("ps -er -o %cpu,command");
        BufferedReader r =  new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        int rowCount = 1;
        while((line=r.readLine())!=null) {
            if(rowCount==2) break; //first row is header
            rowCount++;
        }
        line = line.trim(); // remove spaces in the beginning
        int firstSpacePos = line.indexOf(" ");
        String cpuUsage = line.substring(0, firstSpacePos);
        String processName = line.substring(firstSpacePos+1);
        System.out.println("Process with highest CPU="+processName);
        System.out.println("CPU%="+cpuUsage);
    }
}

The following example program in Java shows the top 5 processes with the highest memory usage on the Mac system,

import java.io.BufferedReader;
import java.io.InputStreamReader;

// Displays the top 5 processes with the highest memory usage in Mac
public class Top5MemoryProcessesInMac {
    public static void main(String[] args) throws Exception {
        printTop5MemoryProcesses();
    }
    
    // Java method to print top 5 processes with highest memory usage in Mac
    private static void printTop5MemoryProcesses() throws Exception {
        Process process = Runtime.getRuntime().exec("ps -em -o %mem,command");
        BufferedReader r =  new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        int rowCount = 0;
        while((line=r.readLine())!=null) {
            System.out.println(line);
            rowCount++;
            if(rowCount>5) break; // note that first line is the header
        }
    }
}

The following example program in Java prints a verbose report of all processes running in the Mac system,

import java.io.BufferedReader;
import java.io.InputStreamReader;

// Displays a verbose report of all running processes in a Mac.
public class VerboseProcessReportInMac {
    public static void main(String[] args) throws Exception {
        printVerboseProcessReport();
    }
    
    // Java program to print verbose process information.
    private static void printVerboseProcessReport() throws Exception{
        Process process = Runtime.getRuntime().exec("ps -er -o %cpu,%mem,flags,lim,lstart,nice,rss,start,state,tt,wchan,command ");
        BufferedReader r =  new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        
        while((line=r.readLine())!=null) {
            System.out.println(line);
        }
    }
}

Additional References

How to Iterate Through a Directory Tree in Java

The following example Java program iterates through all the files and directories in a given folder. It also walks through the entire directory tree printing names of sub-directories and files. Note that this example requires Java 8 or above since it uses java.nio.file.Files class and the walk method in it. The following program has 3 methods,

  • walkDirTree - Walks through the directory tree and print names of directories/files.
  • walkDirTreeWithSymLinks - Demonstrates the use of FileVisitOption for following symbolic links.
  • walkDirTreeAndSearch - Walks through the directory and prints file/directory names matching the search criteria. This method can be used for recursive file search.

Java 8 Files.walk Example Program

import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Paths;

// Java sample program to iterate through directory tree
// Uses the Files.walk method added in Java 8
public class WalkDirectoryTree {
    public static void main(String[] args) throws Exception {
        // in windows use the form c:\\folder
        String rootFolder = "/Users/jj/temp";
        walkDirTree(rootFolder);
        walkDirTreeWithSymLinks(rootFolder);

        String searchFor = "png";
        walkDirTreeAndSearch(rootFolder, searchFor);

    }

    // Prints all file/directory names in the entire directory tree!
    private static void walkDirTree(String rootFolder) throws Exception {
        Files.walk(Paths.get(rootFolder)).forEach(path -> {
            System.out.println(path);
        });
    }

    // This example uses FileVisitOption to follow symbolic links
    // Prints all file/directory names in the entire directory tree
    // Prints all file/directory names in the entire directory tree!
    private static void walkDirTreeWithSymLinks(String rootFolder) throws Exception {
        Files.walk(Paths.get(rootFolder), FileVisitOption.FOLLOW_LINKS).forEach(path -> {
            System.out.println(path);
        });
    }

    // Walk the directory tree looking for files/folder with the search field
    // May throw AccessDeniedException or FileSystemLoopException exception.
    private static void walkDirTreeAndSearch(String rootFolder, String search) throws Exception {
        Files.walk(Paths.get(rootFolder), FileVisitOption.FOLLOW_LINKS).filter(t -> {
            return t.toString().contains(search);
        }).forEach(path -> {
            System.out.println(path);
        });
    }
}

One problem with walk method is that it can potentially throw AccessDeniedException or FileSystemLookException. In such cases, the above program will fail and there is no way to prevent it. One solution is to use the walkFileTree method in such cases. The following sample Java program illustrates the use of walkFileTree. As you can see it is much more verbose than walk example.

Java 8 walkFileTree Example Program

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

//Java sample program to iterate through directory tree
// Uses the walkFileTree method
public class WalkFileTreeDemo {
    public static void main(String[] args) throws Exception{
        // in windows use the form c:\\folder
        String rootFolder = "/Users/jj";
        String searchFor = "png";
        walkFileTreeAndSearch(rootFolder,searchFor);
    }

    private static void walkFileTreeAndSearch(String rootFolder,String search) throws Exception {
        Files.walkFileTree(Paths.get(rootFolder), new MyFileVisitor(search));
    }
}

// There are multiple methods to override in SimpleFileVisitor
// We override only the visitFile method.
class MyFileVisitor extends SimpleFileVisitor<Path> {
    private String search;
    public MyFileVisitor(String s) {
        search = s;
    }
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if(file.toString().contains(search)) {
            System.out.println(file.toString());
        }
        return FileVisitResult.CONTINUE;
    }
}

In addition to the visitFile, the following methods can be overridden from SimpleFileVisitor,

  • preVisitDirectory - Called before contents of a directory is visited
  • postVisitDirectory - Called after contents of a directory is visited
  • visitFileFailed - Called when there is an error such as FileSystemLoopException

The above methods can return one of the following FileVisitResult values,

  • CONTINUE - Continue file tree walk
  • TERMINATE - Terminate file tree walk
  • SKIP_SUBTREE - Continue without visiting the entries in this directory. This result is only meaningful when returned from the preVisitDirectory method; otherwise this result type is the same as returning CONTINUE.
  • SKIP_SIBLINGS - Continue without visiting the siblings of this file or directory. If returned from the preVisitDirectory method then the entries in the directory are also skipped and the postVisitDirectory method is not invoked

Also note that the walkFileTree is faster than the walk method.