Скрипт генерирует приглашения для регистрации на сайте в виде картинки 51x51 пикселей формата PNG, написан на PHP, в качестве базы данных использует MySQL. Сделан ради интереса, будет интересен только новичкам.
С помощью библиотеки GD можно без проблем создавать и редактировать изображения различных форматов. Для создания изображений нам понадобиться несколько функций:
Для начала необходимо создать таблицу в базе данных:
Теперь необходимо сформировать массив 3x4, со значениями красного, зелёного и синего компонентов для каждого из четырёх цветов и записать его в БД.
![](https://habrastorage.org/r/w1560/storage/2c9f85ee/ddffdba9/b7815f9f/393ddf63.png)
P.S. При построение изображения допущена одна неточность, благодаря которой изображения получаются не симметричными.
С помощью библиотеки GD можно без проблем создавать и редактировать изображения различных форматов. Для создания изображений нам понадобиться несколько функций:
int imagecolorallocate(resource image, int red, int green, int blue)
* This source code was highlighted with Source Code Highlighter.
иint imagecolorallocatealpha(resource image, int red, int green, int blue, int alpha)
* This source code was highlighted with Source Code Highlighter.
обе функции возвращают идентификатор цвета для изображения. Единственное отличие в параметре alpha, который задаёт прозрачность изображения. Но так как с PNG прозрачностью в IE издревле были проблемы, то лучше использовать первую функцию. Первый аргумент image можно получить при помощи функции:resource imagecreate(int x, int y)
* This source code was highlighted with Source Code Highlighter.
она возвращает идентификатор изображения, представляющий пустое палитровое изображение размером x на y.Для начала необходимо создать таблицу в базе данных:
CREATE TABLE IF NOT EXISTS `di_invite` (
`invite_id` int(15) unsigned NOT NULL AUTO_INCREMENT,
`invite_hash` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`invite_serialize` text COLLATE utf8_unicode_ci,
`invite_username_owner` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL,
`invite_username_recipient` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`invite_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
* This source code was highlighted with Source Code Highlighter.
В БД будет храниться уникальный идентификатор каждого приглашения(invite_id), hash приглашения(invite_hash), массив с четырьмя RGB-компонентами, в байтово-поточном представление(invite_serialize), никнейм владельца приглашения(invite_username_owner) и никнейм пользователя, активировавшего его(invite_username_recipient).Теперь необходимо сформировать массив 3x4, со значениями красного, зелёного и синего компонентов для каждого из четырёх цветов и записать его в БД.
- function add_invite() {
- // Создаёт четыре случайных цвета и записывает их в массив
- $rgb_array = Array();
- for ($idx=0; $idx < 4; ++$idx) {
- $rgb = array();
- for($idx2 = 0; $idx2 < 3; ++ $idx2) $rgb[] = mt_rand(0, 255);
- $rgb_array[] = $rgb;
- }
- // Преобоазует массив в байтово-поточное представление для записи в БД
- $serialize = serialize($rgb_array);
- // Хэш инвайта
- $hash = md5($serialize);
- // Вставляет
- $_CORE['db']->query('INSERT INTO `di_invite` (`invite_hash`, `invite_serialize`, `invite_username_owner`) VALUES (?, ?, ?);', $hash, $serialize, $_CORE['user']->user_info['user_name']);
- if ($_CORE['db']->affected_rows() == 1) return array(true, 'Инвайт "'.$hash.'" создан');
- else return array(false, 'ERROR - ошибка базы данных');
- return true;
- }
* This source code was highlighted with Source Code Highlighter.
Надо подумать над тем, как это приглашение отдать пользователю. Конечно, легче всего это можно сделать представив его в виде картинки. При генерации изображения надо учесть, что вместо активированного инвайта стоит отдавать чёрно белую картинку, иначе же полноценный четырёхцветный инвайт.
- if (isset($_GET['hash']{31})) {
- // ищет в БД инвайт с таким хэшем
- $result = $_CORE['db']->query('SELECT `di_invite`.`invite_serialize`, `di_invite`.`invite_username_recipient` FROM `di_invite` WHERE `di_invite`.`invite_hash` = ?;', $hash);
- // если нашли
- if ($result && $_CORE['db']->num_rows() == 1) {
- // если инвайт уже использовали, то отдаём чёрно белую картинку
- if ($_CORE['db']->result($result, 0, 'invite_username_recipient') != '') {
- // отдаёи браузеру информацию, о том что это картинка
- header('Content-type: image/png');
- // создаём квадратик 51px на 51px
- $im = ImageCreate(51, 51) or die('Ошибка при создании изображения');
- // выделяет два цвета серый и белый, причём белый будет использован в качестве фона для изображения
- $color[1] = imagecolorallocate($im, 255, 255, 255);
- $color[2] = imagecolorallocate($im, 200, 200, 200);
- // рисует два серых прямоугольника по диагонали
- ImageFilledRectangle($im, 26, 0, 50, 25, $color[2]);
- ImageFilledRectangle($im, 0, 25, 25, 50, $color[2]);
- // Выводит изображение в браузер
- ImagePng($im);
- // Разрушает его
- imagedestroy($im);
- // иначе, если инвайт ещё не использован
- } else {
- // востанавливает массив
- $rgb_array = unserialize(mysql_result($result, 0, 'invite_serialize'));
- header('Content-type: image/png');
- $im = ImageCreate(51, 51) or die('Ошибка при создании изображения');
- // выделяет 4 цвета, из значений массива
- for ($i=0; $i < 4; ++$i)
- $color[$i] = imagecolorallocate($im, $rgb_array[$i][0], $rgb_array[$i][1], $rgb_array[$i][2]);
- // рисует три прямоугольника, чётвёртый (т.е. нулевой элемент массива) цвет по умолчанию являеться фоном изображения
- ImageFilledRectangle($im, 0, 0, 25, 25, $color[1]);
- ImageFilledRectangle($im, 26, 0, 50, 25, $color[2]);
- ImageFilledRectangle($im, 0, 25, 25, 50, $color[3]);
- ImagePng($im);
- imagedestroy($im);
- }
- } else {
- exit();
- }
- } else {
- exit();
- }
* This source code was highlighted with Source Code Highlighter.
Осталось дело за малым, а именно проверить на валидность приглашение. Чтобы это сделать достаточно считать в массив значение цвета в четырёх углах картинки, и попытаться найти хэш получившегося массива в БД.
- function validate_invite($hash_serialize, $userfile) {
- // если при загрузке изображения не было ошибок, размер изображения не превышает допустимый и тип стоответсвует нужному
- if (isset($userfile) && is_uploaded_file($userfile['tmp_name']) && $userfile['size'] < 5*1024 && $userfile['type'] == 'image/png' && $userfile['error'] == 0) {
- // создаём изображение на основе загруженного
- $source = ImageCreateFromPNG($userfile['tmp_name']);
- // определяем точки в которых будет проверяться цвет
- $x[] = 48; $y[] = 48; $x[] = 2; $y[] = 2; $x[] = 48; $y[] = 2; $x[] = 2; $y[] = 48;
- $rgb_array = Array();
- for ($i = 0; $i < 4; ++$i) {
- // получает индекс цвета в точке
- $color_index = imagecolorat($source, $x[$i], $y[$i]);
- // получает цвет для индекса
- $color_tran = imagecolorsforindex($source, $color_index);
- // записываеться в массив
- $rgb = Array();
- $rgb[] = $color_tran['red'];
- $rgb[] = $color_tran['green'];
- $rgb[] = $color_tran['blue'];
- $rgb_array[] = $rgb;
- }
- // преобоазует массив в байтово-поточное представление для сопоставления с записью в массиве
- $serialize_rgb_array = serialize($rgb_array);
- // получает хэш
- $hash_serialize_rgb_array = md5($serialize_rgb_array);
- // ищет запись в бд
- $_CORE['db']->query('SELECT `di_invite`.`invite_id` FROM `di_invite` WHERE `di_invite`.`invite_hash` = ?;', $hash_serialize_rgb_array);
- // если найдено, очищает память, и возвращает true, иначе очищает память и возвращает false
- if ($_CORE['db']->num_rows() < 1) {
- imagedestroy($source);
- return false;
- } else {
- imagedestroy($source);
- $hash_serialize = $hash_serialize_rgb_array;
- return true;
- }
- } else return false;
- }
* This source code was highlighted with Source Code Highlighter.
Получится, что то похожее на:![](https://habrastorage.org/storage/2c9f85ee/ddffdba9/b7815f9f/393ddf63.png)
P.S. При построение изображения допущена одна неточность, благодаря которой изображения получаются не симметричными.