Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Нанесение текстовых водяных знаков на изображение

16.02.2009 | Категория: Web-мастеру и не только | Автор: ManHunter
Для предотвращения воровства контента часто используются водяные знаки на изображениях. Это может быть логотип сайта, надпись об авторских правах или, например, ссылка на ваш сайт. Для нанесения водяных знаков создано множество различных программ, но при наполнении сайта гораздо удобнее использовать скрипт, который будет маркировать картинки сразу при загрузке на сервер. Я написал такую функцию, наносящую нужный текст в указанное место изображения. Ее особенностью является то, что перед нанесением надписи анализируется цвет картинки в месте, где будет расположен текст. Для темных картинок будет выбран белый цвет надписи с черной рамкой, а для светлых наоборот, будет выбран черный цвет надписи с белой рамкой.
  1. //-------------------------------------------------------------------
  2. // Функция нанесения текстового водяного знака на изображение
  3. // Copyright (C) ManHunter / PCL
  4. // http://www.manhunter.ru
  5. //-------------------------------------------------------------------
  6. // Параметры вызова:
  7. // $picture - путь к файлу картинки на сервере
  8. // $font - путь к файлу с TrueType-шрифтом на сервере
  9. // $font_size - размер шрифта
  10. // $marker - текст водяного знака
  11. // $watermark_position - положение водяного знака на картинке
  12. //-------------------------------------------------------------------
  13.  
  14. // Константы положения водяного знака на картинке
  15. define ("WATERMARK_LEFT_BOTTOM",0);
  16. define ("WATERMARK_LEFT_TOP",1);
  17. define ("WATERMARK_RIGHT_BOTTOM",2);
  18. define ("WATERMARK_RIGHT_TOP",3);
  19. define ("WATERMARK_CENTER",4);
  20.  
  21. function Watermark_Image($picture$font$font_size$marker,
  22.                          $watermark_position=WATERMARK_LEFT_BOTTOM) {
  23.   // Проверки на наличие файлов и допустимые параметры
  24.   if (!file_exists($picture)) { return false; }
  25.   if (!file_exists($font)) { return false; }
  26.   if ($font_size<10) { return false; }
  27.   if (($marker=trim($marker))=="") { return false; }
  28.  
  29.   // Получить размеры исходного изображения
  30.   list ($sx,$sy)=GetImageSize($picture);
  31.   if ($sx==|| $sy==0) { return false; }
  32.  
  33.   $dst_im=imageCreatetruecolor($sx,$sy);
  34.  
  35.   // Определить цвета для нанесения водяных знаков
  36.   $black=ImageColorAllocate($dst_im,0,0,0);
  37.   $white=ImageColorAllocate($dst_im,255,255,255);
  38.  
  39.   // Если расширения нет, то выход с ошибкой
  40.   $pocket=Array();
  41.   eregi("\.([a-z]*)$",$picture,$pocket);
  42.   if ($pocket[1]=="") { return false; }
  43.  
  44.   // На основании расширения создать картинку
  45.   switch (strtolower($pocket[1])) {
  46.     case "jpeg":
  47.     case "jpg": {
  48.       if (!$im=@ImageCreateFromJpeg($picture)) { return false; }
  49.       break;
  50.     }
  51.     case "gif": {
  52.       if (!$im=@ImageCreateFromGif($picture)) { return false; }
  53.       break;
  54.     }
  55.     case "png": {
  56.       if (!$im=@ImageCreateFromPng($picture)) { return false; }
  57.       break;
  58.     }
  59.     default: { return false; }
  60.   }
  61.  
  62.   ImageCopyResampled($dst_im$im0000$sx$sy$sx$sy);
  63.   imageDestroy($im);
  64.  
  65.   // Получить координаты блока под текст
  66.   list($lnx,$lny,$rnx,$rny,$rvx,$rvy,$lvx,$lvy) =
  67.      ImageTTFBBox($font_size,0,$font,$marker);
  68.  
  69.   // Вычислить размеры блока
  70.   $text_width=$rnx-$lnx;
  71.   $text_height=$rny-$rvy;
  72.  
  73.   // Получить координаты блока на картинке для нанесения надписи
  74.   switch ($watermark_position) {
  75.     case WATERMARK_LEFT_BOTTOM: {
  76.       $pos_x=10;
  77.       $pos_y=$sy-10;
  78.       break;
  79.     }
  80.     case WATERMARK_RIGHT_BOTTOM: {
  81.       $pos_x=$sx-$text_width-10;
  82.       $pos_y=$sy-10;
  83.       break;
  84.     }
  85.     case WATERMARK_LEFT_TOP: {
  86.       $pos_x=10;
  87.       $pos_y=$text_height+10;
  88.       break;
  89.     }
  90.     case WATERMARK_RIGHT_TOP: {
  91.       $pos_x=$sx-$text_width-10;
  92.       $pos_y=$text_height+10;
  93.       break;
  94.     }
  95.     case WATERMARK_CENTER: {
  96.       $pos_x=intval($sx/2-$text_width/2);
  97.       $pos_y=intval($sy/2+$text_height/2);
  98.       break;
  99.     }
  100.     default: { return false; }
  101.   }
  102.  
  103.   // Подсчитать количество светлых и темных пикселов в блоке
  104.   $dark=0;
  105.   $light=0;
  106.  
  107.   for ($x=0$x<$text_width$x++) {
  108.     for ($y=0$y<$text_height$y++) {
  109.       $color=imageColorAt($dst_im,($pos_x+$x),($pos_y+$y-$text_height));
  110.       list($r,$g,$b)=array_values(imageColorsForIndex($dst_im,$color));
  111.       if (($r+$g+$b)<(128*3)) { $dark++; } else { $light++; }
  112.     }
  113.   }
  114.  
  115.   // В зависимости от количества светлых и темных точек нанести
  116.   // светлую или темную надпись
  117.   if ($light>$dark) {
  118.     // Темный текст со светлой рамкой
  119.     ImageTTFText($dst_im,$font_size,0,$pos_x-1,$pos_y-1,$white,$font,$marker);
  120.     ImageTTFText($dst_im,$font_size,0,$pos_x,$pos_y-1,$white,$font,$marker);
  121.     ImageTTFText($dst_im,$font_size,0,$pos_x+1,$pos_y-1,$white,$font,$marker);
  122.  
  123.     ImageTTFText($dst_im,$font_size,0,$pos_x-1,$pos_y,$white,$font,$marker);
  124.     ImageTTFText($dst_im,$font_size,0,$pos_x+1,$pos_y,$white,$font,$marker);
  125.  
  126.     ImageTTFText($dst_im,$font_size,0,$pos_x-1,$pos_y+1,$white,$font,$marker);
  127.     ImageTTFText($dst_im,$font_size,0,$pos_x,$pos_y+1,$white,$font,$marker);
  128.     ImageTTFText($dst_im,$font_size,0,$pos_x+1,$pos_y+1,$white,$font,$marker);
  129.  
  130.     ImageTTFText($dst_im,$font_size,0,$pos_x,$pos_y,$black,$font,$marker);
  131.   }
  132.   else {
  133.     // Светлый текст с темной рамкой
  134.     ImageTTFText($dst_im,$font_size,0,$pos_x-1,$pos_y-1,$black,$font,$marker);
  135.     ImageTTFText($dst_im,$font_size,0,$pos_x,$pos_y-1,$black,$font,$marker);
  136.     ImageTTFText($dst_im,$font_size,0,$pos_x+1,$pos_y-1,$black,$font,$marker);
  137.  
  138.     ImageTTFText($dst_im,$font_size,0,$pos_x-1,$pos_y,$black,$font,$marker);
  139.     ImageTTFText($dst_im,$font_size,0,$pos_x+1,$pos_y,$black,$font,$marker);
  140.  
  141.     ImageTTFText($dst_im,$font_size,0,$pos_x-1,$pos_y+1,$black,$font,$marker);
  142.     ImageTTFText($dst_im,$font_size,0,$pos_x,$pos_y+1,$black,$font,$marker);
  143.     ImageTTFText($dst_im,$font_size,0,$pos_x+1,$pos_y+1,$black,$font,$marker);
  144.  
  145.     ImageTTFText($dst_im,$font_size,0,$pos_x,$pos_y,$white,$font,$marker);
  146.   }
  147.  
  148.   // Записать измененный файл на место
  149.   switch (strtolower($pocket[1])) {
  150.     case "jpeg":
  151.     case "jpg": {
  152.       ImageJPEG($dst_im,$picture,90);
  153.       break;
  154.     }
  155.     case "gif": {
  156.       ImageGIF($dst_im,$picture);
  157.       break;
  158.     }
  159.     case "png": {
  160.       ImagePNG($dst_im,$picture);
  161.       break;
  162.     }
  163.   }
  164.   imageDestroy($dst_im);
  165.   return true;
  166. }
Параметры вызова функции: $picture - полный путь к файлу на сервере, поддерживаются форматы JPG, GIF, PNG. Файл должен быть доступен для записи, так как после нанесения водяного знака он будет перезаписан с тем же именем. $font - путь к файлу с TrueType-шрифтом, который должен быть размещен на сервере. $font_size - размер шрифта надписи, рекомендуется 12. $marker - текстовая строка водяного знака, если используется кириллица, то она должна быть в Юникоде. $watermark_position - положение надписи на картинке, необязательный параметр. Доступные значения определены константами, прочие значения игнорируются: 0 - левый нижний угол (значение по умолчанию), 1 - левый верхний угол, 2 - правый нижний угол, 3 - правый верхний угол, 4 - центр изображения.

Читать статью целиком »
Просмотров: 12801 | Комментариев: 10

Парсер REFERER'ов с поисковых систем

04.02.2009 | Категория: Web-мастеру и не только | Автор: ManHunter
Обработка заголовка HTTP referer является одной из важных задач при раскрутке сайта и сборе статистики. По нему можно определить, какие ресурсы ссылаются на ваш сайт. Но особую ценность представляют данные посещений с поисковых систем, так как эта информация позволяет наиболее четко определить, по каким ключевым словам ваш сайт может быть найден, а также проанализировать эффективность поисковой оптимизации вашего ресурса. Если вы пользуетесь сторонними счетчиками посещений, то эту информацию они обычно предоставляют сами. В некоторых случаях такие данные предоставляют серверные системы статистики типа Webalizer. Я принципиально не пользуюсь ни тем, ни другим, обрабатываю все данные самостоятельно. Для этого была написана функция обработки рефереров, которую я использую в своих проектах. Данные поискового запроса обычно передаются методом GET и содержатся в строке браузера, но основная проблема в том, что кодировка этих данных может быть разной даже в пределах одной и той же поисковой системы. Как выяснилось, не везде доступна штатная функция PHP is_unicode(), поэтому для подстраховки пришлось написать свою. Проверка выполняется согласно правилам формирования Юникода.
  1. // Функция проверки является ли переменная строкой в Юникоде 
  2. // Если штатная функция не определена, то применить нашу
  3. if (!function_exists('is_unicode')) {
  4.   function is_unicode($str) {
  5.     for ($i=0$i<strlen($str); $i++) {
  6.       // Если символ с кодом больше 191, то возможно это юникод
  7.       if (ord($str[$i])>191) {
  8.         // Следующий символ должен быть в интервале
  9.         // 10000000b ... 10111111b (128...191)
  10.         if (ord($str[($i+1)])<128 || ord($str[($i+1)])>191) {
  11.           // Условие не выполнено, значит это не юникод
  12.           return false;
  13.         }
  14.         else {
  15.           // Пропускаем один байт, т.к. он является частью символа
  16.           $i++;
  17.         }
  18.       }
  19.     }
  20.     // Проверка пройдена, это юникод
  21.     return true;
  22.   }
  23. }
Теперь, когда мы можем четко определить кодировку строки запроса, нам необходимо выделить ее из строки URL. Для этого достаточно выполнить в интересуемом поисковике любой запрос и посмотреть как формируется ссылка.

Читать статью целиком »
Просмотров: 30411 | Комментариев: 27

Шпаргалки для Web-мастера по HTML, CSS и JavaScript

30.11.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
В свое время преподаватели учили меня: "Не надо всего знать, надо знать где взять". Для больших объемов информации я, конечно, предпочитаю бумажные справочники. А когда надо быстро посмотреть синтаксис какой-нибудь редко используемой функции, параметры тега или код цвета, то очень выручают онлайн-справочники и файлы-шпаргалки. Вот основные сайты и ресурсы для облегчения поиска.

Целые каталоги шпаргалок по различным языкам программирования предлагают сайты TechCheatSheets.com, gotAPI, WhatIs.com и refcards.com. Последний сайт уже давно не обновлялся.

Большой набор файлов-шпаргалок по PHP, Apache, mod_rewrite, CSS, JavaScript, HTML, MySQL, ASP, VBScript и другие можно найти на сайте Added Bytes. Они выполнены в формате PDF и PNG.

Отдельно шпаргалки по JavaScript выложены на сайте JavaScript Reference, использование регулярных выражений в JavaScript можно посмотреть на сайте VisiBone. При желании там же можно за денежку заказать наборы шпаргалок в бумажном виде.

Онлайновый справочник по HTML и CSS на русском языке на сайте htmlbook.ru, а в виде шпаргалок на сайте HTML Tags. Справочники по CSS с примерами здесь и здесь. Справочник по CSS на русском языке выложен на сайте Александра Климова, а на сайте CSSplay вы можете посмотреть интересные примеры верстки с использованием CSS.

Таблицу HTML-цветов можно посмотреть на сайте VisiBone или скачать в формате PDF с сайта Veign.

Читать статью целиком »
Просмотров: 21024 | Комментариев: 13

Проверка принадлежности IP-адреса заданному диапазону

19.11.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Проверка вхождения IP в заданный диапазон может применяться во многих ситуациях. Например бан всей подсетки злоумышленника, принудительное ограничение скорости для зарубежного трафика, переадресация на различные разделы сайта в зависимости от провайдера пользователя и т.д. Я использую такие функции:
  1. // ------------------------------------------------------------
  2. // Проверка вхождения IP в заданный диапазон
  3. // На входе:
  4. // $ip - массив октетов проверяемого IP
  5. // $ip_start - массив октетов начала интервала
  6. // $ip_end - массив октетов конца интервала
  7. // В интервалах допускаются маски '*'
  8. // На выходе: TRUE или FALSE, входит IP или нет в диапазон
  9. // ------------------------------------------------------------
  10. function chk_ips($ip,$ip_start,$ip_end) {
  11.   for ($i=0$i<4$i++) {
  12.     if ($ip_start[$i]=='*') { $ip_start[$i]='0'; }
  13.     if ($ip_end[$i]=='*') { $ip_end[$i]='255'; }
  14.   }
  15.   $ip_num=ip2long(join('.',$ip));
  16.   if ($ip_num>=ip2long(join('.',$ip_start)) 
  17.       && $ip_num<=ip2long(join('.',$ip_end))) {
  18.     // IP входит в интервал
  19.     return true;
  20.   }
  21.   else {
  22.     // IP не входит в интервал
  23.     return false;
  24.   }
  25. }
Функция универсальная, позволяет обрабатывать одиночные IP-адреса, точно заданные диапазоны и диапазоны с маской "*" в любом октете. Дополнительных проверок на корректность диапазонов не производится.

Читать статью целиком »
Просмотров: 18109 | Комментариев: 1

Отправка сообщений на ICQ из PHP-скриптов

09.11.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Для отправки сообщений на ICQ из PHP-скриптов очень удобно использовать готовый класс WebIcqPro от автора Сергея Акудовича. Этот класс может послужить основой для создания ICQ-роботов, системы оповещения о различных событиях с сайтов, удаленного администрирования через ICQ и многого другого. WebIcqPro не требует установки на сервере дополнительных компонентов и библиотек. Достаточно подключить через include сам класс в ваш PHP-скрипт и воспользоваться его методами и свойствами. Для работы WebIcqPro требуется PHP 5.2.0 и выше. Класс активно развивается и скоро будет включать в себя практически все функции протокола Oscar. Если по каким-либо причинам на сервере установлена более старая версия PHP, то можно воспользоваться облегченной версией класса WebIcqLite. В ней есть только функции отправки и получения сообщений, но обычно этого вполне достаточно. Класс неплохо документирован, все описания на русском языке, методы и свойства приведены с примерами использования. Очень хороший скрипт, пользуюсь сам и другим рекомендую.

Помните, что на сервере ICQ установлена защита от брутфорса, и при частых подключениях аккаунт блокируется на несколько десятков минут. Поэтому если для вашего проекта критично, чтобы все сообщения были отправлены, то зарегистрируйте несколько ICQ-аккаунтов и отправляйте сообщения с них по очереди или выбирая один случайным образом. Количество необходимых аккаунтов определяется опытным путем в зависимости от нагрузки.

Просмотров: 15439 | Комментариев: 16

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.1 сек. / MySQL: 3 (0.0065 сек.) / Память: 4.5 Mb
Наверх