Descriere:Cum sa citesti textul dintr-o poza captcha
Download:Nu necesita
Autor:In script
Sursa (Link-ul oficial): Propria parere:Util.
Tutorialul:
În acest tutorial vom învăţa să citim textul dintr-o imagine de tip captcha. Să zicem că:
- culoarea background-ului este aleatoare
- culoarea cifrelor este mereu aceeaşi
- poziţia cifrelor diferă pe X
- poziţia cifrelor rămâne neschimbată pe Y
Practic, trebuie să afişăm în format text cifrele din imaginea de tip captcha (evident, sunt aleatoare). Să vedem în continuare codul .php care generează imaginile:
Cod:
Cod: Selectaţi tot
<?php
header('Content-type: image/png');
$img = imagecreate(239, 25);
$r = rand(1, 255);
$g = rand(1, 255);
$b = rand(1, 255);
$l1 = rand(0, 4);
$l2 = rand(0, 4);
$l3 = rand(0, 4);
$l4 = rand(0, 4);
$l5 = rand(0, 4);
$poz1 = rand(0, 48);
$poz2 = $poz1 + rand(9, 48);
$poz3 = $poz2 + rand(9, 48);
$poz4 = $poz3 + rand(9, 48);
$poz5 = $poz4 + rand(9, 48);
$background = imagecolorallocate($img, $r, $g, $b);
$culoare = imagecolorallocate($img, 100, 100, 100);
imagechar($img, 7, $poz1, 6, $l1, $culoare);
imagechar($img, 7, $poz2, 6, $l2, $culoare);
imagechar($img, 7, $poz3, 6, $l3, $culoare);
imagechar($img, 7, $poz4, 6, $l4, $culoare);
imagechar($img, 7, $poz5, 6, $l5, $culoare);
imagepng($img);
?>
Primul pas constă în eliminarea culorilor. Background-ul imaginii va deveni alb, iar cifrele vor avea culoarea neagră. Să vedem codul php:
Cod:
Cod: Selectaţi tot
<?php
$img = imagecreatefrompng("http://site.com/captcha/cap1.png");
$alb = imagecolorallocate($img, 255, 255, 255);
$negru = imagecolorallocate($img, 0, 0, 0);
//Simplificarea imaginii
//Background alb
//Scris de culoare neagra
for ($i=0; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixel = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $pixel);
if ($rgb['red']!=100 && $rgb['green']!=100 && $rgb['blue']!=100) {
imagesetpixel($img, $i, $j, $alb);
}
else {
imagesetpixel($img, $i, $j, $negru);
}
}
}
//Finished simplificare
?>
2) Găsire dreptunghiuri cifre.
Cum am spus, cifrele sunt plasate random pe axa oX. Ideea este că noi trebuie să împărţim imaginea iniţială (cea mare/cap1.png) în 5 imagini mai mici, fiecare conţinând doar o cifră!
Un amănunt foarte important este că fontul default folosit la funcţia imagechar() este monospaced (courier din câte ştiu), iar orice cifră "scrisă" cu font size=7 poate fi încadrată într-un dreptunghi de lungime 9.
Deci spre exemplu, ca să găsesc prima cifră, trebuie să găsesc primul pixel de culoare neagră (căutarea pornind de la stânga la dreapta) şi să îi reţin X-ul. Apoi extrag dreptunghiul de la X până la X+8. Codul PHP:
Cod:
Cod: Selectaţi tot
<?php
//Gasire dreptunghi prima cifra
for ($i=0; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixel = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $pixel);
if ($rgb['red']==0 && $rgb['green']==0 && $rgb['blue']==0) {
$istart = $i; $ifinal = $i+8; break 2;
}
}
}
//Gasire dreptunghi a 2-a cifra
for ($i=$ifinal+1; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixel = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $pixel);
if ($rgb['red']==0 && $rgb['green']==0 && $rgb['blue']==0) {
$iistart = $i; $iifinal = $i+8; break 2;
}
}
}
//Gasire dreptunghi a 3-a cifra
for ($i=$iifinal+1; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixel = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $pixel);
if ($rgb['red']==0 && $rgb['green']==0 && $rgb['blue']==0) {
$iiistart = $i; $iiifinal = $i+8; break 2;
}
}
}
//Gasire dreptunghi a 4-a cifra
for ($i=$iiifinal+1; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixel = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $pixel);
if ($rgb['red']==0 && $rgb['green']==0 && $rgb['blue']==0) {
$ivstart = $i; $ivfinal = $i+8; break 2;
}
}
}
//Gasire dreptunghi a 5-a cifra
for ($i=$ivfinal+1; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixel = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $pixel);
if ($rgb['red']==0 && $rgb['green']==0 && $rgb['blue']==0) {
$vstart = $i; $vfinal = $i+8; break 2;
}
}
}
//Finished gasire dreptunghiuri
?>
Cod:
Cod: Selectaţi tot
<?php
//Impartire in 5 imagini
//Cropuire de la stanga la dreapta
$img1=imagecreate(9, 25);
$img2=imagecreate(9, 25);
$img3=imagecreate(9, 25);
$img4=imagecreate(9, 25);
$img5=imagecreate(9, 25);
imagecopyresampled ($img1, $img, 0, 0, $istart, 0,9, 25, 9, 25);
imagecopyresampled ($img2, $img, 0, 0, $iistart, 0,9, 25, 9, 25);
imagecopyresampled ($img3, $img, 0, 0, $iiistart, 0,9, 25, 9, 25);
imagecopyresampled ($img4, $img, 0, 0, $ivstart, 0,9, 25, 9, 25);
imagecopyresampled ($img5, $img, 0, 0, $vstart, 0,9, 25, 9, 25);
//Finished cropuire de la stanga la dreapta
?>
3) Compararea imaginilor.
Acum că am obţinut imaginile care conţin cifrele (0, 1, 2, 3, 4), le salvăm pe server pentru a face comparaţii mai târziu. Ca să le putem folosi în scriptul php, trebuie să folosim următorul cod:
Cod:
Cod: Selectaţi tot
<?php
$cif[0] = imagecreatefrompng("cifre/0.png");
$cif[1] = imagecreatefrompng("cifre/1.png");
$cif[2] = imagecreatefrompng("cifre/2.png");
$cif[3] = imagecreatefrompng("cifre/3.png");
$cif[4] = imagecreatefrompng("cifre/4.png");
?>
Cod:
Cod: Selectaţi tot
<?php
//Functie comparare imagini
function comparare($imagine12, $cifra12) {
$true = 0;
for ($i=0; $i<239; $i++) {
for ($j=0; $j<25; $j++) {
$pixelx = imagecolorat($imagine12, $i, $j);
$pixely = imagecolorat($cifra12, $i, $j);
if ($pixelx != $pixely) {
//Difera un pixel
$true = 1; break 2;
}
}
}
return $true;
}
//End functie
//Comparari imagini & stuff
//Daca returneaza 0, imaginile sunt identice
//Daca returneaza 1, imaginile sunt diferite
//Si trecem sa comparam cu urmatoarea
for ($x=0; $x<=4; $x++) {
$value=comparare($img1, $cif[$x]);
if ($value==0) {
echo $x."\r\n"; break;
}
}
for ($x=0; $x<=4; $x++) {
$value=comparare($img2, $cif[$x]);
if ($value==0) {
echo $x."\r\n"; break;
}
}
for ($x=0; $x<=4; $x++) {
$value=comparare($img3, $cif[$x]);
if ($value==0) { echo $x."\r\n"; break; }
}
for ($x=0; $x<=4; $x++) {
$value=comparare($img4, $cif[$x]);
if ($value==0) { echo $x."\r\n"; break; }
}
for ($x=0; $x<=4; $x++) {
$value=comparare($img5, $cif[$x]);
if ($value==0) { echo $x."\r\n"; break; }
}
?>
Autorul nu îşi asumă nici o responsabilitate în cazul folosirii acestor informaţii în scopuri ilegale, scopul acestui tutorial este pur informativ.