Make ascii art from image

Make ascii art from image

2014-01-02

ASCII​‌‍​‌​‌‍​‍ is the name given to a computer table that associates numbers a letter of the alphabet. Pronounced aski, this acronym stands for “American Standard Code for Information Interchange” and has now been expanded into an international goal in a new standard called UTF-8.


ASCII Art is a way of representing in color or black and white an image, using only the available characters in the ASCII code. The character of Catwoman DC comics universe could then be represented as follows:



                 0                           M
8 D 0
M X0## M
7 MM 0MN7DXDXM# 0
#0MMM 00XMMM00MX0M8
#08MM 0M#77DD80M#MM
MM0# XT|D/:DNMMMM#D
#MN# TD|7D8XMMM0 #
8 MM00 DDT780#M#M
0MX0X D80###MX#0
X0T7MX X0XT/NX0M00MMN X
M00N8XM00X000XX0MM00MMMMM0M0 X
XMNT80XDXXM00MMMMMMM0MMMMMXMMN
#0D0MMMMMMMMMMMXDDX00M0MNM#MMM
M NMMM#M0XNX0MMXMMM0MMXMMX
0N888MMM000XMMMMMM0MMM#MNMT
M#M0NM0MMM000MMM0MMMM#MMM0M#
MM0MMMX000MMMMMMMMXM#MM#MD0M7
00MM000MMMMMMMMMMM#0 MD|0M
X DMM800MMMMM#MMMM0 D0NDM#
0 0MMD0MMMMM###M#M NM00#M
0 XMN8MMMMMMMM##X MMMM0
X #M07M#M#MMMM## 0MM#M
X0XMNMMMMMMMM# MM8MM
X MMM8DMMMMM#MM#M 80DMMM
0 |MM0D/TMMMMMMM0MM N0000
8M0XT.TNMMM##00M#0 #MMM
# 80MM0N700MM#MM778MM0 0M
X:#MMMMMX000MMMMMDDDNMMN
MMMM#MM000MMMMMMM0NX0M#0 #0
X#MMMM0MMMMMMMMMMMM00MM##M .T
DMMMM00MMMMMMM#MMMMMMMMM##M
##MM00MMM#########MMM######
#MNX########0 T###########M M
8#MN8M####### XX####M#MM#MX #
0MMMXXM#####| X0MM00MMM##M7 M.
##MM00#####7 N##M00MMM##M
##MMMM##### 0M##MMM####|

We will see in this tutorial how to turn an image into ASCII art, to perform it we will use the PHP programming language and image manipulation library GD.


A digital image is an array of pixels in two dimensions, each of which is of a color. Each color is represented by its level of red, green and blue.


Let’s create a function in our php file that will take the following parametters, the path to the image, color management, the maximum length of characters per line and the list of characters to use from the clearest to darkest.


<?php
/
Transforme une image en chaine ASCII @param imagePath : Le chemin phisique de l’image
@param colors : Gestion des couleurs ou non dans le résultat @param length : longueure maximal d’une ligne
@param characters : liste des caractères a utiliser, du plus claire au plus foncé @return la chaine de caractère du ASCII art, null si echec
*/
function getAsciiMapFromImage($imagePath, $colors = false, $length = 150, $characters = array(‘ ‘, ‘\’’, ‘.’, ‘:’,’|’, ‘/‘, ‘7’, ‘T’, ‘D’, ‘7’, ‘D’, ‘8’, ‘N’, ‘X’, ‘0’, ‘M’,’#’))
{
return null;
}

To begin, check if the image is on the server and load it into the application memory and then determine the length and height and determine the ratio of size to be used not to distort the image or only use a part.


We will also reverse the order of the list of characters in order to save computation and also to place its cardinality in a variable.


<?php
/
Transforme une image en chaine ASCII @param imagePath : Le chemin phisique de l’image
@param colors : Gestion des couleurs ou non dans le résultat @param length : longueure maximal d’une ligne
@param characters : liste des caractères a utiliser, du plus claire au plus foncé @return la chaine de caractère du ASCII art, null si echec
/
function getAsciiMapFromImage($imagePath, $colors = false, $length = 150, $characters = array(‘ ‘, ‘\’’, ‘.’, ‘:’,’|’, ‘/‘, ‘7’, ‘T’, ‘D’, ‘7’, ‘D’, ‘8’, ‘N’, ‘X’, ‘0’, ‘M’,’#’))
{
if(file_exists($imagePath))
{
$image = imagecreatefromstring(file_get_contents($imagePath));
list($width, $height) = getimagesize($imagePath);

$scale = $width/$length;

$characters = array_reverse($characters);
$characters_count = count($characters);
$characters_last_elm = $characters_count - 1;
}
return null;
}

It must then go through the image pixel by pixel to extract the color at this point, extract each color level, calculating the saturation of all so as to determine the character that best matches the intensity of a color desired.


The character is then concatenated with all of the outgoing channel. At the end of each line you add the newline character.


If the color parameter to true and it is not of the lightest character, a span tag with the CSS style representing the color will be added.


<?php
/** Transforme une image en chaine ASCII
@param imagePath : Le chemin phisique de l’image @param colors : Gestion des couleurs ou non dans le résultat
@param length : longueure maximal d’une ligne @param characters : liste des caractères a utiliser, du plus claire au plus foncé
@return la chaine de caractère du ASCII art, null si echec /
function getAsciiMapFromImage($imagePath, $colors = false, $length = 150, $characters = array(‘ ‘, ‘\’’, ‘.’, ‘:’,’|’, ‘/‘, ‘7’, ‘T’, ‘D’, ‘7’, ‘D’, ‘8’, ‘N’, ‘X’, ‘0’, ‘M’,’#’))
{
if(file_exists($imagePath))
{
$image = imagecreatefromstring(file_get_contents($imagePath));
list($width, $height) = getimagesize($imagePath);

$scale = $width/$length;

$characters = array_reverse($characters);
$characters_count = count($characters);
$characters_last_elm = $characters_count - 1;

$return_string = ‘’;

for($y = 0; $y <= $height - $scale - 1; $y += $scale) {
for($x = 0; $x <= $width - ($scale / 2) - 1; $x += ($scale / 2)) {
$rgb = imagecolorat($image, $x, $y);
$red = (($rgb >> 16) & 0xFF);
$green = (($rgb >> 8) & 0xFF);
$blue = ($rgb & 0xFF);
$sat = ($red + $green + $blue) / (255 3);
$char = $characters[ (int)( $sat
$characters_last_elm ) ];
if($colors && $char != $characters[$characters_last_elm])
$return_string.= ‘<span style=”color:rgb(‘.$red.’, ‘.$green.’, ‘.$blue.’);”>’.$char.’</span>’;
else
$return_string.= $char;
}
$return_string .= PHP_EOL;
}

return $return_string;
}
return null;
}

You can now enjoy your ASCII Art by calling the function on the desired image to the size you want.


<!– Utilisation d’un balise pre de mannière a ne pas perdre les saut de ligne et les espaces –>
<pre><?php echo getAsciiMapFromImage(‘robin.jpg’, true, 60);?></pre>

This tutorial and downloadable scripts are under the following Creative Common license : http://creativecommons.org/licenses/by-nc-sa/3.0/fr/.