J’ai fait un pari. Petit challenge à réaliser : faire un script (peu importe le langage) qui prend en paramètre un fichier image, et qui en sort de l’ASCII art.
Il faut qu’il soit rapidement paramétrable sur la taille des fontes.
Je l’ai fait « théorique » en 59 minutes, mais entièrement fonctionnel en une heure trente. J’ai fait deux scripts : un qui génère le fichier des fontes, et le principal qui lit le fichier image des fontes, et le fichier image en paramètre, et sort de l’ASCII art.
Exemple de résultat (si si c’est bien du texte, vous pouvez le sélectionner et copier coller en tant que texte !) :
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBMBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB¨ MBBBBBBMM0BBB
BBBBBBBBBBBBBBBBBBBBBBBBBP'`BB ,BBBP¨ MBB
BBBBBBBBBBBBBBBBBBBBBBBBB& %BMBPBBL ,a ¨BB
BBBBBBBBBBBBBBBBBBBBBBBBBB jBB MBBaBBP BB
BBBBBBBBBBBBBBBBBBBBBBBBPM BB ¨BBB^ , 0B
BBBBBBBBBBBBBBBBBBBBBBP` BBb BB' mB jB
BBBBBBB@P'BBBBBB@M@BBB mB $BK 0B jBP ¨B
BBBBBBBK BBBP^` MBB dBB MBB jB ¨ L,aB
B^¨ 'BBB %BB ,a BB &BBL BB Bh ,WBBBB
B ¨BB jBB,mBM^ $B 'BBF BBL BBBBBBBBBB
BL `BL BBBP¨ jB ^^ %B&mBBBBBBBBBBB
B& w ¨& BBP wB B& wamBBBBBBBBBBBBBBB
BB %w MBL BB¨ BBBwamBBBBBBBBBBBBBBBBBB
BB MBw ¨BK ¨`, ,&BBBBBBBBBBBBBBBBBBBBBBB
BBL BBN BB, aBBBBBBBBBBBBBBBBBBBBBBBBBBB
BB& BBBh 0BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBB MBBBhwmBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBB OBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Ne regardez pas la suite si vous voulez essayer de le faire pour vous !
<?php
function usage_et_exit($message = '', $exit_error = -1) {
global $argv;
if ($message != '') {
echo $message."\n";
}
echo $argv[0]." {image gif reference} {image noir et blanc jpg}\n";
exit($exit_error);
}
function noir_ou_blanc($r, $g, $b) {
/* http://stackoverflow.com/questions/254388/how-do-you-convert-an-image-to-black-and-white-in-php */
if (((0.299*$r) + (0.587*$g) + (0.114*$b))> 0x7F) {
return 0xFFFFFF;
} else {
return 0x000000;
}
}
function cherche_meilleure_correspondance(
$img_src, $x, $y, $img_fonts, $font_size, $tab_base
) {
$meilleur = -1;
$retour = '';
foreach ($tab_base as $idx => $ch) {
$match = 0;
for ($t_y=0; $t_y<$font_size; $t_y++) {
for ($t_x=0; $t_x<$font_size; $t_x++) {
if (imagecolorat($img_src, $t_x+$x, $t_y+$y)
!= imagecolorat(
$img_fonts,
($idx*$font_size) + $t_x, $t_y
)
) {
$match++;
}
}
}
if ($match>$meilleur) {
$retour = $ch;
$meilleur = $match;
}
}
return $retour;
}
function convert_img_noir_et_blanc($filename, $img)
{
list($width, $height, $type, $attr) = getimagesize($filename);
/* Conversion en noir et blanc */
for ($y=0; $y<$height; $y++) {
for ($x=0; $x<$width; $x++) {
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$nb = noir_ou_blanc($r, $g, $b);
imagesetpixel($img, $x, $y, $nb);
}
}
}
$tab_base = array(
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '&', '\'', ',', ';', ':', '?', '.', '/', '!',
'%', '^', '¨', '$', '~', '#', '(', ')', '[', ']', '|', '-', '`', ' '
);
$font_size = 14;
$min_width = 400;
$min_height = 400;
if ($argc!=3) {
usage_et_exit("Arguments invalides", -1);
}
$img_tmp = imagecreatefromstring(file_get_contents($argv[1]));
$width = imagesx($img_tmp);
$height = imagesy($img_tmp);
$img_fonts = imagecreatetruecolor($width, $height);
imagecopy($img_fonts, $img_tmp, 0, 0, 0, 0, $width, $height);
imagedestroy($img_tmp);
unset($img_tmp);
if ($img_fonts===false) {
usage_et_exit("Erreur chargement de ".$argv[1], -1);
}
/* Conversion en noir et blanc des fontes */
convert_img_noir_et_blanc($argv[1], $img_fonts);
imagepng($img_fonts, './resultat_fonts.png', 0);
list($width, $height, $type, $attr) = getimagesize($argv[2]);
if ($width<$min_width) {
usage_et_exit("Largeur trop petite de ".$argv[1].", taille min = ".$width_min, -1);
}
if ($width<$min_height) {
usage_et_exit("Hauteur trop petite de ".$argv[1].", taille min = ".$width_min, -1);
}
$img_src = imagecreatefromjpeg($argv[2]);
if ($img_src===false) {
usage_et_exit("Erreur chargement de ".$argv[2], -1);
}
convert_img_noir_et_blanc($argv[2], $img_src);
/* Ok on a l'image en noir et blanc. Parcourir toute l'image */
imagepng($img_src, './resultat_noir_et_blanc.png', 0);
$y = 0;
$max_result = 0;
while (($y + $font_size) < $height) {
$x = 0;
while (($x + $font_size) < $width) {
echo cherche_meilleure_correspondance(
$img_src, $x, $y, $img_fonts, $font_size, $tab_base
);
$x += $font_size;
}
echo "\n";
$y += $font_size;
}
echo "Done.\n";
?>
Et le fichier qui génère les fontes (22 minutes de perdues à le faire…) :
<?php
$tab_base = array(
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '&', '\'', ',', ';', ':', '?', '.', '/', '!',
'%', '^', '¨', '$', '~', '#', '(', ')', '[', ']', '|', '-', '`', ' '
);
$x=0;
$font_size = 14;
$width = count($tab_base)*$font_size;
echo 'width='.var_export($width,true)."\n";
$height = $font_size*4;
$img = imagecreatetruecolor($width, $height);
if ($img===false) {
throw new Exception("Erreur");
}
imagefilledrectangle($img, 0, 0, $width, $height, 0xFFFFFF);
foreach ($tab_base as $idx => $char) {
$ok = imagettftext(
$img,
$font_size, 0,
$idx * $font_size, $font_size,
0x000000,
'./consola.ttf', $char
);
}
imagegif($img, './test.gif');
echo "Done.\n";
?>