DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Integrating AWS With Salesforce Using Terraform
  • The Role of AI and Programming in the Gaming Industry: A Look Beyond the Tables
  • Database Integration Tests With Spring Boot and Testcontainers
  • Mainframe Development for the "No Mainframe" Generation

Trending

  • Integrating AWS With Salesforce Using Terraform
  • The Role of AI and Programming in the Gaming Industry: A Look Beyond the Tables
  • Database Integration Tests With Spring Boot and Testcontainers
  • Mainframe Development for the "No Mainframe" Generation
  1. DZone
  2. Coding
  3. Java
  4. Ascii Art Generator in Java - Part 2

Ascii Art Generator in Java - Part 2

Ivan Korhner user avatar by
Ivan Korhner
·
Apr. 04, 15 · Interview
Like (1)
Save
Tweet
Share
2.96K Views

Join the DZone community and get the full member experience.

Join For Free

since i got a lot of feedback for my my previous post where i built a very simple ascii art generator in java (find it on github ), i decided to continue with the project and add some more features to it you will hopefully enjoy even more. i’ve redesigned the major part of it and made it very extensible so it is very easy to use to test different algorithms, create different outputs, etc. in this post, i will present the new architecture of the project, so you can easily integrate it into your own code and extend it as needed.

architecture:

_config.yml


asciiimgcache

before any ascii art rendering takes place, it is necessary to create an instance of this class. it takes a font and a list of characters to use as parameters and it creates a map of images for every character. there is also a default list of characters if you don’t want to bother comming up with your own.
in case you are curious:

private static final char[] defaultcharacters = 
    "$@b%8&wm#*oahkbdpqwmzo0qlcjuyxzcvunxrjft/\\|()1{}[]?-_+~<>i!li;:,\"^`'. "

example:

// use only '/' '\' and ' '
asciiimgcache mediumblackandwhitecache = asciiimgcache.
    create(new font("courier", font.bold, 10), new char[] {'\\', ' ', '/'});

// use default list
asciiimgcache largefontcache = asciiimgcache.
    create(new font("courier",font.plain, 16));

bestcharacterfitstrategy

this is the abstraction of the algorithm used for determining how similar a part of the source image with each character is. it has one method:

float calculateerror(final grayscalematrix character, final grayscalematrix tile);

the implementation should compare two images and return a float error. each character will be compared and the one that returns the lowest error will be selected. currently there two implementations available: colorsquareerrorfitstrategy and structuralsimilarityfitstrategy.

colorsquareerrorfitstrategy

very simple to understand, it compares every pixel and calculates mean squared error of the grayscale differences. mathematically speaking its:
_config.yml
where n is the number of pixels, and c and t are pixels from character and tile image respectively.

structuralsimilarityfitstrategy

the structural similarity (ssim) index algorithm claims to reproduce human perception and its aim is to improve on traditional methods like mse. i will not get into much details about how it works, you can read more on wikipedia if you want to know more. i experimented a bit with it and implemented a version that seemed to produce the best results for this case.


asciiconverter

this is the hearth of the process and it contains all the logic for tiling source image and utilizing concrete implementations for calculating character best fit. however, it doesn’t know how to create the concrete ascii art - it needs to be subclassed. there are two implementations currently: asciitoimageconverter and asciitostringconverter - which as you probably guessed, produce image and string output.


example usage

since a code snippet is worth a thousand words, i will show you the whole process in action that should wrap up all the pieces:

// initialize cache
asciiimgcache cache = asciiimgcache.create(new font("courier",font.bold, 6));

// load image
bufferedimage portraitimage = imageio.read(new file("image.png"));

// initialize converters
asciitoimageconverter imageconverter = 
    new asciitoimageconverter(cache, new colorsquareerrorfitstrategy());
asciitostringconverter stringconverter = 
    new asciitostringconverter(cache, new structuralsimilarityfitstrategy());

// image output
imageio.write(imageconverter.convertimage(portraitimage), "png", 
    new file("ascii_art.png"));
// string converter, output to console
system.out.println(stringconverter.convertimage(portraitimage));

here are some sample images generated with various parameters:

original picture

16 pts font, mse
16 pts font, ssim
10 pts font with 3 characters, mse
10 pts font with 3 characters, ssim
6 pts font, mse
6 pts font, ssim

further work

some ideas that i have in mind:

  • research and try to implement more image comparison algorithms
  • try to preprocess the image to get better results (improve contrast, use edge detection, etc.)
  • image processing could be parallelized for performance improvent, try it and measure the gain to see if is worth it.
  • add some more converters (i.e. html output)
  • add support for output with colored characters
  • add tests to the project

if have any ideas for improvement or find any problems with the code, feel free to comment or contribute to this repository via github !

ASCII art ARTS (radiative transfer code) Java (programming language)

Published at DZone with permission of Ivan Korhner, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Integrating AWS With Salesforce Using Terraform
  • The Role of AI and Programming in the Gaming Industry: A Look Beyond the Tables
  • Database Integration Tests With Spring Boot and Testcontainers
  • Mainframe Development for the "No Mainframe" Generation

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: