[Tutorial PHP]Cum sa citesti textul dintr-o poza captcha

#1
Nume Tutorial:Cum sa citesti textul dintr-o poza captcha
Descriere:Cum sa citesti textul dintr-o poza captcha
Download:Nu necesita
Autor:In script
Sursa (Link-ul oficial):
tutorialeonline.net
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);
 ?>
1) Background - alb, cifre - negru.

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
 ?>
cap1.png reprezintă imaginea care urmează să fie "citită". Se observă din cod că cifrele (care au r, g, b = 100) sunt setate la culoarea neagră, iar restul pixelilor la alb. Acum imaginea este alb-negru.

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
 ?>
Am găsit ceea ce aveam nevoie (valorile sunt reţinute în variabilele $istart, $iistart, $iiistart, $ivstart, $vstart). Acum trebuie să dăm crop la imaginea iniţială pentru a extrage exact aceste cifre (pt. asta folosim funcţia imagecopyresampled):
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
 ?>
Din ceea ce se vede mai sus, cifrele sunt salvate în imagini de 9x25.

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");
 ?>
Ce ne mai rămâne de facut? Să comparăm pixelii lui $img1, $img2, $img3, $img4, $img5 cu fiecare dintre $cif[0], $cif[1], $cif[2], $cif[3], $cif[4], pe rând. Dacă $img1 coincide cu $cif[2], atunci cifra corespunzătoare este 2.
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; }
 }
 ?>
Asta e tot. Aţi reuşit să citiţi un captcha ! Felicitări.
Autorul nu îşi asumă nici o responsabilitate în cazul folosirii acestor informaţii în scopuri ilegale, scopul acestui tutorial este pur informativ.
N-am cerut la nimeni niciodata,
Chiar de-a fost sa rabd, in viata mea.
Am dat totul fara nici o plata,
Nevoind nimic sa mi se dea.

@Virgil Carianopol
Vezi-ti de treaba si retine:
"E treaba ta sa spui ce vrei si sa nu conteze pentru nimeni".

@Kazi Ploae

Înapoi la “Tutoriale PHP”

Cine este conectat

Utilizatori răsfoind acest forum: Niciun utilizator înregistrat și 0 vizitatori