DbHelp.ru
Маленький Yii блог
Комментарии
Гость: wh0cd2594827 [url=http://pyridium911.us.com/]Pyridium[/url] [url=http://clozaril911.us.org/]clozaril...
Гость: order Retrovir in USA delivery NO PRESCRIPTION ; low prices Retrovir in Canada pharmacy without ...
Гость: wh0cd3078423 [url=http://sildenafil04.us.org/]sildenafil citrate generic[/url] [url=http://xenical02...
Гость: wh0cd2594827 [url=http://dapoxetine911.us.com/]dapoxetine[/url] [url=http://lisinopril03.us.com/]40 ...
Гость: buy essays essay buying order essay now https://buyessay.us.com - college essay helper



Сервер Ultima Online - Forest Wars (от создателя данного блога)

Настройка 3d капчи на Yii

Рубрика: Работаем с капчей (captcha)

Оцените эту статью:

Рейтинг: 0.00 (0)
18 Апр. 2009
Опубликовать в Twitter Написать в Facebook Опубликовать в своем блоге livejournal.com

Эта статья устарела т.к. была написана для yii версии 1.0.х; Если вы используете более новую версию - у вас могут возникнуть ошибки из-за несовместимости. Обычно ответы на все вопросы работы на 1.1.х были описаны в комментариях ниже статьи.

Yii Framework Blog img http://dbhelp.rucap4-3d Честно сказать не думал что когда то буду ковырять капчу более чем на уровне настройки, но не тут то было. Спасибо romanoza за ссылку на 3d капчу которая сразу меня заинтересовала.

---

Посидел я пару минут в прочтении комментариев на хабре и обнаружил ссылку на либсу с исходным кодом http://code.google.com/p/3dcaptcha/. (Именно её я решил прикрутить к Yii).

Yii Framework Blog img http://dbhelp.rucap2-3d Если вам вдруг захотелось такую капчу на сайте – я расскажу как её прикрутить, но для начала вы должны убедиться что:
1.    Ваш сайт написан на Yii
2.    У вас уже есть страница с капчей и в одном из ваших контроллеров есть код:

public function actions()
{
    return array(
        'captcha'=>array(
            ….
            'class'=>'CCaptchaAction',
          ….
        ),
    );
}
Если у вас нет капчи – вы можете прочитать статью про то, как её установить.

Давайте теперь всё-таки приступим.
Заходим protected/components/ и создаем там файл Yii3dCaptcha.php :

/**
 * 3dCaptcha class file
 *
 * Данный клас позволяет вместо стандартной капчи на вашем сайте -
 * выводить красивую 3д. Все параметры (кроме width/height/padding)
 * работают и могут быть использованы для изменения: цвета текста,
 * цвета фона, количества букв.
 *
 * Дополнительный параметр fontSize - задает размер текста.
 *
 * @author Alekseenko Timur <[email protected]>
 * @license GNU General Public License v3
 * @link http://dbhelp.ru
 * @link http://code.google.com/p/3dcaptcha
 */
class Yii3dCaptcha extends CCaptchaAction
{
    /**
     * Размер текста
     * @var <type>
     */
    public $fontsize = 24;

    /**
     * Рендер капчи
     * @param <type> $code
     */
    function renderImage($code)
    {
        if($this->fontFile===null)
        $this->fontFile = dirname(__FILE__).'/views/3dCaptcha/3DCaptcha.ttf';

        $details = imagettfbbox($this->fontsize, 0, $this->fontFile, $code);
        $image2d_x = $details[4] + 4;
        $image2d_y = $this->fontsize * 1.3;

        $bevel = 4;

        $image2d = imagecreatetruecolor($image2d_x, $image2d_y);
        $black = imagecolorallocate($image2d, 0, 0, 0);
        $white = imagecolorallocate($image2d, 255, 255, 255);

        imagefill($image2d, 0, 0, $black);
        imagettftext($image2d, $this->fontsize, 0, 2, $this->fontsize, $white, $this->fontFile, $code);

        $T = $this->cameraTransform(
                array(rand(-90, 90), -200, rand(150, 250)),
                array(0, 0, 0)
            );

        $T = $this->matrixProduct(
                $T,
               $this->viewingTransform(60, 300, 3000)
            );

        $coord = array($image2d_x * $image2d_y);
        $count = 0;
        for ($y = 0; $y < $image2d_y; $y+=2) {
            for ($x = 0; $x < $image2d_x; $x++) {
                $xc = $x - $image2d_x / 2;
                $zc = $y - $image2d_y / 2;
                $yc = -(imagecolorat($image2d, $x, $y) & 0xff) / 256 * $bevel;
                $xyz = array($xc, $yc, $zc, 1);
                $xyz = $this->vectorProduct($xyz, $T);

                $coord[$count] = $xyz;
                $count++;
            }
        }

        $image3d_x = 256;
        $image3d_y = $image3d_x * 9 / 16;
        $image3d = imagecreatetruecolor($image3d_x, $image3d_y);
        $fgcolor = imagecolorallocate($image3d,
        (int)($this->foreColor%0x1000000/0x10000),
        (int)($this->foreColor%0x10000/0x100),
        $this->foreColor%0x100);

        $bgcolor = imagecolorallocate($image3d,
        (int)($this->backColor%0x1000000/0x10000),
        (int)($this->backColor%0x10000/0x100),
        $this->backColor%0x100);

        imageantialias($image3d, true);
        imagefill($image3d, 0, 0, $bgcolor);
        $count = 0;
        $scale = 1.75 - $image2d_x/400;
        for ($y = 0; $y < $image2d_y; $y++) {
            for ($x = 0; $x < $image2d_x; $x++) {
                if ($x > 0) {
                    $x0 = $coord[$count - 1][0] * $scale + $image3d_x / 2;
                    $y0 = $coord[$count - 1][1] * $scale + $image3d_y / 2;
                    $x1 = $coord[$count][0] * $scale + $image3d_x / 2;
                    $y1 = $coord[$count][1] * $scale + $image3d_y / 2;
                    imageline($image3d, $x0, $y0, $x1, $y1, $fgcolor);
                }
                $count++;
            }
        }

        header('Pragma: public');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Transfer-Encoding: binary');
        header("Content-type: image/png");
        imagepng($image3d);
        imagedestroy($image3d);
    }

    function addVector($a, $b) {
        return array($a[0] + $b[0], $a[1] + $b[1], $a[2] + $b[2]);
    }

    function scalarProduct($vector, $scalar) {
        return array($vector[0] * $scalar, $vector[1] * $scalar, $vector[2] * $scalar);
    }

    function dotProduct($a, $b) {
        return ($a[0] * $b[0] + $a[1] * $b[1] + $a[2] * $b[2]);
    }

    function norm($vector) {
        return sqrt($this->dotProduct($vector, $vector));
    }

    function normalize($vector) {
        return $this->scalarProduct($vector, 1 / $this->norm($vector));
    }

    function crossProduct($a, $b) {
        return array(
            ($a[1] * $b[2] - $a[2] * $b[1]),
            ($a[2] * $b[0] - $a[0] * $b[2]),
            ($a[0] * $b[1] - $a[1] * $b[0])
            );
    }

    function vectorProductIndexed($v, $m, $i) {
        return array(
            $v[$i + 0] * $m[0] + $v[$i + 1] * $m[4] + $v[$i + 2] * $m[8] + $v[$i + 3] * $m[12],
            $v[$i + 0] * $m[1] + $v[$i + 1] * $m[5] + $v[$i + 2] * $m[9] + $v[$i + 3] * $m[13],
            $v[$i + 0] * $m[2] + $v[$i + 1] * $m[6] + $v[$i + 2] * $m[10]+ $v[$i + 3] * $m[14],
            $v[$i + 0] * $m[3] + $v[$i + 1] * $m[7] + $v[$i + 2] * $m[11]+ $v[$i + 3] * $m[15]
            );
    }

    function vectorProduct($v, $m) {
        return $this->vectorProductIndexed($v, $m, 0);
    }

    function matrixProduct($a, $b) {
        $o1 = $this->vectorProductIndexed($a, $b, 0);
        $o2 = $this->vectorProductIndexed($a, $b, 4);
        $o3 = $this->vectorProductIndexed($a, $b, 8);
        $o4 = $this->vectorProductIndexed($a, $b, 12);

        return array(
            $o1[0], $o1[1], $o1[2], $o1[3],
            $o2[0], $o2[1], $o2[2], $o2[3],
            $o3[0], $o3[1], $o3[2], $o3[3],
            $o4[0], $o4[1], $o4[2], $o4[3]
            );
    }

    function cameraTransform($C, $A) {
        $w = $this->normalize($this->addVector($C, $this->scalarProduct($A, -1)));
        $y = array(0, 1, 0);
        $u = $this->normalize($this->crossProduct($y, $w));
        $v = $this->crossProduct($w, $u);
        $t = $this->scalarProduct($C, -1);

        return array(
            $u[0], $v[0], $w[0], 0,
            $u[1], $v[1], $w[1], 0,
            $u[2], $v[2], $w[2], 0,
            $this->dotProduct($u, $t), $this->dotProduct($v, $t), $this->dotProduct($w, $t), 1
            );
    }

    function viewingTransform($fov, $n, $f) {
        $fov *= (M_PI / 180);
        $cot = 1 / tan($fov / 2);

        return array(
            $cot,    0,        0,        0,
            0,        $cot,    0,        0,
            0,        0,        ($f + $n) / ($f - $n),        -1,
            0,        0,        2 * $f * $n / ($f - $n),    0
            );
    }
}

Это расширение класса CCaptchaAction и менять в нем ничего не надо!

Yii Framework Blog img http://dbhelp.rucap1-3d Теперь нам надо создать папку где будет находится шрифт для капчи, для этого войдите в protected/components/views и создайте там папку 3dCaptcha. После этого скачайте шрифт 3DCaptcha.ttf (отсюда) и загрузите его в эту папку.

Вот в принципе и всё. Теперь нам осталось только войти в наш контроллер в котором задаются настройки для вашей капчи и изменить название класса. Заходим в ваш контроллер и находим там:

public function actions()
{
    return array(
        'captcha'=>array(
            ….
            'class'=>'CCaptchaAction',
          ….
        ),
    );
}

Yii Framework Blog img http://dbhelp.rucap3-3d Изменяем 'CCaptchaAction' на 'Yii3dCaptcha' и сохраняем файл. Теперь если вы войдете на страницу где у вас выводилась старая капча – вы увидите красивую 3d.

Если вы хотите изменить цвет фона, цвет текста и кол-во символов в капче – прочитайте мою статью «Изменяем нашу капчу».

В следующей статье про капчи я расскажу Вам как заставить капчу говорить русскими буквами. 

Всем спасибо, заходите еще :)



Если хотите опубликовать этот материал у себя - пожалуйста, разместите ссылку на страницу откуда вы его взяли.
Другие yii статьи:

  1. Александр Макаров на страницах yiiframework.ru опубликовал перевод очень хорошего рецепта. Хочу заметит что материал будет очень полезен для тех, кто ... "Краткий справочник по валидации форм"

  2. Просматривая сегодня официальный форум фреймворка столкнулся с новой, но достаточно интересной темой. next ... "С чего начать изучать Yii?"

  3. Я очень рад объявить о выходе новой версии моего любимого Yii Framework 1.1.3 В этом выпуске разработчики исправили около 20 найденных ... "Релиз Yii framework 1.1.3"

romanoza

Было сказано: Воскресенье, 19 Апрель 2009

только вот тут еще шумы есть и синусоида
http://www.pict.com/view/313989/0/test

[adm] zolter

Было сказано: Воскресенье, 19 Апрель 2009

Я шумы не ставил потому что вобще тогда непонятно что на капче :)

[guest] Гость

Было сказано: Четверг, 30 Апрель 2009

Супер капча!

[guest] Kros

Было сказано: Пятница, 16 Апрель 2010

капча интересная, но ни в какую не отображается, простым классом - всё норм, а в 3d - есть только кнопка "новый код". в чём может быть дело?
несколько раз всё проверил - всё на местах вроде, версия 1.1.1. Может в ней по-другому нужно?
Такое чувство, что yii просто не видит компонент, пробовал так:
'class'=>'application.components.Yii3dCaptcha'
безрезультатно

[guest] zolter

Было сказано: Пятница, 16 Апрель 2010

Сейчас попробую у себя на 1.1.1 поднять, до этого только на 1.0.х тестил

[adm] zolter

Было сказано: Пятница, 16 Апрель 2010

На 1.1.1 таки не работает. Сейчас разберемся

[adm] zolter

Было сказано: Пятница, 16 Апрель 2010

Не получилось завести, потом еще поковыряю.
Если у кого есть время то узнал что ругается на строчки:


$x0 = $coord[$count - 1][0] * $scale + $image3d_x / 2;
$y0 = $coord[$count - 1][1] * $scale + $image3d_y / 2;
$x1 = $coord[$count][0] * $scale + $image3d_x / 2;
$y1 = $coord[$count][1] * $scale + $image3d_y / 2;


т.е. иногда $count переваливает за размер массива $coord и ругается что нет такого элемента. поэтому надо разобратся почему либо $coord такой маленький создается, либо цикл где count так долго идет.

[guest] Kros

Было сказано: Пятница, 16 Апрель 2010

спасибо что поковырял))), пока простой попользуюсь))

[adm] zolter

Было сказано: Пятница, 16 Апрель 2010

Та не проблема, самому интересно что за фигня :)

[guest] RedDog

Было сказано: Воскресенье, 06 Февраль 2011

Необходимо исправить следующее:
строку $image2d_y = $this->fontsize * 1.3; на $image2d_y = (int)($this->fontsize * 1.3);
строке $coord = array($image2d_x * $image2d_y); на $coord = array();

Привести в соответствие циклы, где обходится массив $coord:
либо строку for ($y = 0; $y < $image2d_y; $y+=2) (первый цикл, в котором происходит заполнение массива $coord) исправить на for ($y = 0; $y < $image2d_y; $y++) (в итоге на капче будут чаще расположены линии),
либо строку for ($y = 0; $y < $image2d_y; $y++) (второй цикл) исправить на строку for ($y = 0; $y < $image2d_y; $y+=2) чтобы $count не выходил за пределы массива

[guest] zolter

Было сказано: Воскресенье, 06 Февраль 2011

Вот за это большое спасибо!

[guest] Гость

Было сказано: Понедельник, 04 Сентябрь 2017

Курсы массажа для младенцев Черкассах. Лучших трудоустроим! Что входит в курс: Полный курс 25 занятий. Мини группы до 8-ми обучающихся. Предусмотрено изучение по сокращенной схеме. Длительность занятий два часа. Бесплатное занятие. Разрешена оплата по частям. Цена 1900 гривен. Итоговый экзамен. Курсы массажа для младенцев Черкассах. Качество и Результат! Вы присматриваете где бы научиться массажу? Идите в STAIR-LIFE Почему выбирают школу массажа stair-life: Вы стараетесь быть ближе к своему партнеру, открывать внутренний мир вас обоих Вы желаете изучить подходящее вам занятие и иметь высокий доход Вы осознаете важность здоровья своей семьи Имеете стремление приносить пользу окружающим Мы работаем для: Для Реабилитологов Тех, кто занимается духовными практиками Всех, кто хочет круто изменить свой образ жизни к лучшему Для людей, которые ценят свое время и свободу Каждого желающего нести людям красоту и приятные эмоции Тех, кто старается заботиться о своем теле Почти каждый человек страдает от: Малоподвижный образ жизни Постоянные стрессы Боль в позвоночнике Расстройства пищеварения Тугоподвижность суставов Профессиональные массажисты, работающие в больших городах привлекают к себе новаторскими видами и дополнениями к массажу За время обучения вы сможете узнать: О особенностях лечебного массажа Строении кожи и мышц Способы воздействия на организм Как организовать свой кабинет Меры предосторожности Наши мастера знают массаж не по наслышке, все они практикующие массажисты и обучают не сухой теории, а живому опыту Преподаватели не только дадут нужную информацию а именно то что пригодиться вам в работе. Ваша практика начнется в первый же урок Уроки в Стаирлайф помогут изучить наиболее востребованные массажные техники и найти отлично оплачиваемую должность массажиста. Стоимость обучения в нашей школе основывается на грамотном сочетании цены к качеству.

Оставить комментарий


Код:
Имя: