Création à la volée d'une image contenant des caracteres
qui devront être reconnus et saisis par un être humain
Avant d'installer ce genre de limitation, il faut considérer le fait que cela empèche l'utilisation du formulaire par les aveugles et les mal-voyants, et donc réfléchir à la nécessité réelle de ce dispositif.
Cela dit, voici un exemple d'image générée par ce script :
nouveau
Il peut etre appelé dans le html de la facon suivante : <img id='texte_image' src='texte_image.php'>
Il peut être testé dans le php comme ceci : if ($caracteres_saisis <> $_SESSION['texte_image'])...
Enfin, pour que l'utilisateur de votre formulaire puisse, à volonté changer l'image : <a onclick = "document.getElementById('texte_image').src = 'texte_image.php?'+Math.random()">nouveau </a>
Ce script fonctionne avec des polices de caracteres true type (.ttf), mais il est particulierment cohérent avec la police suivante : alfr_ho.ttf. Cette police est libre de droit.
<?php
// script gratuit et libre de droit de oBlog.fr :
// ce script produit une image avec des caracteres, qui devrton être reconnu par un etre humain
// il peut etre appeler dans le html de la facon suivante : <img id='texte_image' src='texte_image.php'>
// et tester dans le php comme ceci : if ($caracteres_saisis <> $_SESSION['text_image'])...
// pour que l'utilisateur de votre formulaire puisse, à volonté changer l'image : <a onclick="document.getElementById('texte_image').src='texte_image/texte_image.php?'+Math.random()">nouveau </a>
// la police alfr_ho.ttf est libre de droit et disponible sur oBlog.fr : http://oblog.fr/oblog.phtml?article_afficher=27
//mise a nul de la reference session du texte correspondant a l'image
session_start();
$_SESSION['texte_image']='';
// nombre de carateres
$nombre_caracteres = 6;
// taille de l'image et de la police
$taille_y = 150;
$taille_max_police = round($taille_y * 0.45);
$taille_x=round($nombre_caracteres*$taille_max_police*0.9);
// police (c'est l'addresse du fichier qui doit être présent sur votre site)
$fichier_police = 'alfr_ho.ttf';
// Création de l'image (vide)
$image = imagecreatetruecolor($taille_x, $taille_y);
// Création des couleurs
define('ROUGE',0);
define('VERT',1);
define('BLEU',2);
$couleur_lettre = array(ROUGE =>0, VERT =>0, BLEU =>0);
$couleur_fond = array(ROUGE =>255,VERT =>255,BLEU =>255);
//remplissage du fond
$couleur = imagecolorallocate($image,$couleur_fond[ROUGE],$couleur_fond[VERT],$couleur_fond[BLEU]);
imagefilledrectangle($image, 0, 0, $taille_x-1, $taille_y-1, $couleur);
// ecriture des caracteres
// construction de la couleur
$couleur = imagecolorallocate($image,$couleur_lettre[ROUGE],$couleur_lettre[VERT],$couleur_lettre[BLEU]);
// police (c'est une URL...)
$fichier_police = 'alfr_ho.ttf';
// caracteres possible dans l'image
// sont absents les caracteres ambigus dans un affichage déformé
$alphabet='acefgimnopsuvwxyz';
$taille_alphabet = strlen($alphabet);
// ecriture des caracteres
$x_lettre = 10;
for ($i=1;$i<=$nombre_caracteres;$i++)
{
// choix d'un caractere
$caractere=$alphabet[mt_rand(0,$taille_alphabet-1)];
// taille de la police
$taille_police = round($taille_max_police*mt_rand(70,100)/100);
// choix d'un ange d'ecriture entre -15 et 15 degré
$angle=mt_rand(-20,20);
// ecriture de la lettre dans l'image
$rectangle=imagettfbbox ($taille_police,$angle,$fichier_police, $caractere);
imagettftext($image, $taille_police, $angle, $x_lettre,($taille_y/5*3), $couleur, $fichier_police, $caractere);
// calcul du declage en x
$rectangle=imagettfbbox ($taille_police,$angle,$fichier_police, $caractere);
$x_lettre = round(($x_lettre+$rectangle[2]-$rectangle[0])*0.92);
// sauvegarde de la lettre dans la reference session
$_SESSION['texte_image'].=$caractere;
}
// deformations en Y
$longueur_min=40;
$longueur_max=70;
$amplitude_min = 5;
$amplitude_max = 8;
$x_fin=0;
$x_debut=0;
// definition des deformations successives
while ($x_debut<$taille_x)
{
$courbe['longueur'] = round(mt_rand($longueur_min,$longueur_max));
$courbe['x_debut']=$x_debut;
$courbe['x_fin']=$x_debut+$courbe['longueur'];
if ($courbe['x_fin']>=$taille_x-1-$longueur_min)
{
$courbe['x_fin']>$taille_x-1;
$courbe['longueur']=$courbe['x_fin']-$courbe['x_debut'];
}
if (mt_rand(-1,1)>=0)
$sens=1;
else
$sens=-1;
$courbe['amplitude']=mt_rand($amplitude_min,$amplitude_max)*$sens;
$courbes[]=$courbe;
$x_debut=$courbe['x_fin']+1;
}
// application des courbes
$image_temporaire_1 = imagecreatetruecolor ($taille_x, $taille_y);
for ( $x=0 ; $x < $taille_x ; ++$x )
{
$y_decale=0;
foreach ($courbes as $courbe)
if (($x > $courbe['x_debut']) and ($x <$courbe['x_fin']))
{
$x_courbe = $x - $courbe['x_debut'];
$radian=($x_courbe/$courbe['longueur']*M_PI*2);
$y_decale = round(((1-cos($radian)) * $courbe['amplitude']));
break;
}
for ( $y=0 ; $y < $taille_y ; ++$y )
{
$y_courbe = $y+$y_decale;
if ($y_courbe<0) $y_courbe = 0;
if ($y_courbe>=$taille_y) $y_courbe = $taille_y-1;
$couleur=imagecolorat($image, $x, $y_courbe);
imagesetpixel($image_temporaire_1,$x,$y,$couleur);
}
}
// deformations en X
$longueur_min=40;
$longueur_max=70;
$amplitude_min = 2;
$amplitude_max = 4;
$y_fin=0;
$y_debut=0;
// definition des courbes
$courbes=array();
while ($y_debut<$taille_y)
{
$courbe['longueur'] = round(mt_rand($longueur_min,$longueur_max));
$courbe['y_debut']=$y_debut;
$courbe['y_fin']=$y_debut+$courbe['longueur'];
if ($courbe['y_fin']>=$taille_y-1-$longueur_min)
{
$courbe['y_fin']>$taille_y-1;
$courbe['longueur']=$courbe['y_fin']-$courbe['y_debut'];
}
if (mt_rand(-1,1)>=0)
$sens=1;
else
$sens=-1;
$courbe['amplitude']=mt_rand($amplitude_min,$amplitude_max)*$sens;
$courbes[]=$courbe;
$y_debut=$courbe['y_fin']+1;
}
// application des courbes
for ( $y=0 ; $y < $taille_y ; ++$y )
{
$x_decale=0;
foreach ($courbes as $courbe)
if (($y > $courbe['y_debut']) and ($y <$courbe['y_fin']))
{
$y_courbe = $y - $courbe['y_debut'];
$radian=($y_courbe/$courbe['longueur']*M_PI*2);
$x_decale = round(((1-cos($radian)) * $courbe['amplitude']));
break;
}
for ( $x=0 ; $x < $taille_x ; ++$x )
{
$x_courbe = $x+$x_decale;
if ($x_courbe<0) $x_courbe = 0;
if ($x_courbe>=$taille_x) $x_courbe = $taille_x-1;
$couleur=imagecolorat($image_temporaire_1, $x_courbe,$y);
imagesetpixel($image,$x,$y,$couleur);
}
}
// retourner l'image codée en JPEG
header("Content-type: image/jpeg");
imagejpeg($image);
?>