Как я чистил капчу

Discussion in 'PHP' started by wirusoalll, 6 Mar 2012.

  1. wirusoalll

    wirusoalll New Member

    Joined:
    2 Mar 2012
    Messages:
    10
    Likes Received:
    4
    Reputations:
    0
    Привет.
    Решил написать свою первую статейку, как я чистил капчу вида
    [​IMG]

    В общем что я сделал первым делом так это посмотрел её под увеличением.

    [​IMG]

    Ну в моем случае это была самая простая капча с шумом в один пиксель разных цветов, оставалось придумать алгоритм.
    Но сразу что пришло на ум так это скрипт который я писал для прохождения лабиринта и поиска кратчайшего пути. Суть в том что робот останавливался и смотрел в 4 стороны, если он видел выход то к переменной прибавлял единичку в итоге он получал количество возможных ходов.(но так я этот скрипт и не сделал, видимо маловато php знаю, потом попробую)
    Я решил воплотить именно эту мысль, просто брать пиксель смотреть его цвет, и сравнивать с цветами вокруг, если цвет совпадает то это уже часть цифры или буквы капчи и так же прибавим к нашей переменной едичичку.
    потом смотрим если у переменной 0 то значит этот пиксель один единственный то есть и есть шум который мы закрасим в цвет фона.

    И так приступим
    Code:
    $img = @imagecreatefrompng('default.png');
    header ('Content-Type: image/png');
    
    ну это стандартная всем знакомая функция(знакомая для тех кто занимается php)
    то есть открыли файл записали его переменную $img
    далее нам надо всю картинку скопировать на новый слой
    Code:
    $img_o = imagecreatetruecolor(80, 20);
    imagecopy($img_o, $img, 0, 0, 0, 0, 80, 20);
    
    размеры слоя 80x20 тут я решил сразу указать размеры т.к работает это с таким видом капч.
    Скопировали на новый слой $img_o
    Почему скопировали ,а не начали производить действия с уже открытой капчей, так из за того что если не копировать а сразу делать чистку то на выходе у меня получается вот такой вариант
    [​IMG]

    Почему так получается я не знаю(Кто знает напишите) т.к я сам не слишком долго программирую на php и это как бы мой первый такой серьезный скрипт(Для меня серьезный, для вас может и смешной)

    Ладно поехали дальше
    создаем ещё слой на котором мы будем вырисовывать уже капчу без шума
    Code:
    $new_image = imagecreatetruecolor(80, 20);
    
    я назвал её $new_image тоже размер 80х20

    ну теперь нам надо две строчки кода которые будут(как бы это сказать) будут читать с 1 по 80*20=1600 пиксель(последний)
    Code:
    for($x=0;$x<80;$x++){
     for($y=0;$y<20;$y++){
    
    ага хорошо сделали такую, теперь помнится я вам говорил про переменную, назовем её просто(зачем же что то осложнять) познакомьтесь это
    Code:
    $r = 0;
    
    А вот этой строчкой
    Code:
    $rgb = imagecolorat($img_o,$x,$y);
    
    мы читаем цвет пикселя и загоняем его в переменную $rgb(не думайте что я школоло который спер эту статью от куда ни будь, нет это не так я простой студент 1 курса,который просто не обладает даром объяснения того что сам сделал)

    так теперь сама фишка в чтении пикселей вокруг основного пикселя
    Code:
     if(imagecolorat($img_o,$x-1,$y) == $rgb){
          $r++;
         }
    
    тут мы просто смотрим верхний пиксель $x-1 который находится над основным пикселем и сравниваем цвета если цвет совпал, то увеличиваем переменную $r на единичку(ой не думал что так трудно статьи писать и попытаться передать смысл :( )
    вот полностью код проверки
    Code:
     if(imagecolorat($img_o,$x-1,$y) == $rgb){
          $r++;
         }
           if(imagecolorat($img_o,$x+1,$y) == $rgb){
             $r++;
            }
             if(imagecolorat($img_o,$x,$y-1) == $rgb){
               $r++;
              }
               if(imagecolorat($img_o,$x,$y+1) == $rgb){
                $r++;
                }
    
    красиво?да!
    Криво?Ну для моего уровня само ТО :)
    так,а теперь просто смотрим
    Code:
     if($r == 0){
        imagesetpixel($new_image,$x,$y,'15265527');
          }else{
              imagesetpixel($new_image,$x,$y,$rgb);
                 }
     }
    
    Если $r == 0 то этот пиксель абсолютно один(как в попе дырочка) то рисуем этот пиксель уже на новом слое в цвет фона в моем случае это 15265527, а если больше $r>0 то это как я уже говорил часть буквы или цифры, ну и самый последний штрих это закрыть for
    и вывести картинку
    imagepng($new_image);
    И получить результат равный этому
    [​IMG]

    Полный код выглядит так
    Code:
    <?php
    $img = @imagecreatefrompng('default.png');
    header ('Content-Type: image/png');
    
    $img_o = imagecreatetruecolor(80, 20);
    imagecopy($img_o, $img, 0, 0, 0, 0, 80, 20);
    
    $new_image = imagecreatetruecolor(80, 20);
    
    for($x=0;$x<80;$x++){
     for($y=0;$y<20;$y++){
       $r = 0;
       $rgb = imagecolorat($img_o,$x,$y);
         if(imagecolorat($img_o,$x-1,$y) == $rgb){
          $r++;
         }
           if(imagecolorat($img_o,$x+1,$y) == $rgb){
             $r++;
            }
             if(imagecolorat($img_o,$x,$y-1) == $rgb){
               $r++;
              }
               if(imagecolorat($img_o,$x,$y+1) == $rgb){
                $r++;
                }
                     if($r == 0){
                    	imagesetpixel($new_image,$x,$y,'15265527');
                      }else{
                        imagesetpixel($new_image,$x,$y,$rgb);
                      }
     }
    }
    imagepng($new_image);
    ?>
    
    Вот и все.Я кое как справился со своей первой статьей=)
    если понравилось,то могу написать как я её учил распознавать

    только на forum.antichat.ru
     
    #1 wirusoalll, 6 Mar 2012
    Last edited: 7 Mar 2012
    2 people like this.
  2. wirusoalll

    wirusoalll New Member

    Joined:
    2 Mar 2012
    Messages:
    10
    Likes Received:
    4
    Reputations:
    0
    Ну да понимаю что сейчас такими капчами не пользуются, но просто мне это было интересно с точки зрения практики
     
  3. petryxa-mixa

    petryxa-mixa Member

    Joined:
    8 Jun 2010
    Messages:
    174
    Likes Received:
    7
    Reputations:
    0
    статья по распознание будет помойму полезнее даже.
    Напиши я как раз хотел почитать про такие вещи.
    Покульней оформи только не забудь.
     
  4. wirusoalll

    wirusoalll New Member

    Joined:
    2 Mar 2012
    Messages:
    10
    Likes Received:
    4
    Reputations:
    0
    Хорошо, уже приступил к написанию
     
  5. InSys

    InSys Member

    Joined:
    2 Feb 2012
    Messages:
    24
    Likes Received:
    20
    Reputations:
    31
    wirusoalll, вы меня извините конечно, но это ужасно =(

    Во первых, оформите статью нормально с помощью тегов [CODE ][/CODE ]

    Во вторых,
    ЧТО ЭТО?! На мой взгляд, когда люди заходят в эту статью, они хотят почитать про алгоритмы "чистки капч", а не описание справки по PHP. Я бы посоветовал оформить это в виде отдельного скрипта с комментариями (и то почитайте статьи про то какие моменты в вашей программе стоит комментировать а какие нет).