Blog. Just Blog

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

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

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

13.07.2009 | Категория: Web-мастеру и не только | Автор: ManHunter
Наносить текстовые надписи на картинки средствами PHP мы уже умеем. Теперь рассмотрим как делать то же самое, только на этот раз вместо текста будет графический маркер. Сам маркер представляет собой картинку в формате PNG-8 (глубина цвета - 8 бит), допускается прозрачность и произвольная форма. Если маркер будет с другой глубиной цвета, то при наложении прозрачный цвет будет заменен на черный. Другой формат маркеров не поддерживается! Файл PNG определяется по расширению, можно анализировать внутреннюю структуру, но это, наверное, в данном случае лишнее и остается на совести вебмастера.
  1. //-------------------------------------------------------------------
  2. // Функция нанесения графического водяного знака на изображение
  3. // Copyright (C) ManHunter / PCL
  4. // http://www.manhunter.ru
  5. //-------------------------------------------------------------------
  6. // Параметры вызова:
  7. // $picture - путь к файлу картинки на сервере
  8. // $marker - путь к файлу водяного знака на сервере
  9. // $opacity - процент прозрачности
  10. // $watermark_position - положение водяного знака на картинке
  11. //-------------------------------------------------------------------
  12.  
  13. // Константы положения водяного знака на картинке
  14. define ("WATERMARK_LEFT_BOTTOM",0);
  15. define ("WATERMARK_LEFT_TOP",1);
  16. define ("WATERMARK_RIGHT_BOTTOM",2);
  17. define ("WATERMARK_RIGHT_TOP",3);
  18. define ("WATERMARK_CENTER",4);
  19.  
  20. function Watermark_PNG_Image($picture$marker$opacity=100,
  21.                            $watermark_position=WATERMARK_RIGHT_BOTTOM) {
  22.   // Проверки на наличие файлов и допустимые параметры
  23.   if (!file_exists($picture)) { return false; }
  24.   if (!file_exists($marker)) { return false; }
  25.  
  26.   // Получить размеры исходного изображения
  27.   list ($sx,$sy)=GetImageSize($picture);
  28.   if ($sx==|| $sy==0) { return false; }
  29.  
  30.   // Получить размеры маркера
  31.   list ($mx,$my)=GetImageSize($marker);
  32.   if ($mx==|| $my==|| $sx<($mx+20) || $sy<($my+20)) { return false; }
  33.  
  34.   // Если расширение маркера не .PNG, то выход с ошибкой
  35.   if (strtolower(substr($marker,-4))!=".png") { return false; }
  36.  
  37.   // Если расширения нет, то выход с ошибкой
  38.   $pocket=Array();
  39.   eregi("\.([a-z]*)$",$picture,$pocket);
  40.   if ($pocket[1]=="") { return false; }
  41.  
  42.   // На основании расширения создать картинку
  43.   switch (strtolower($pocket[1])) {
  44.     case "jpeg":
  45.     case "jpg": {
  46.       if (!$im=@ImageCreateFromJpeg($picture)) { return false; }
  47.       break;
  48.     }
  49.     case "gif": {
  50.       if (!$im=@ImageCreateFromGif($picture)) { return false; }
  51.       break;
  52.     }
  53.     case "png": {
  54.       if (!$im=@ImageCreateFromPng($picture)) { return false; }
  55.       break;
  56.     }
  57.     default: { return false; }
  58.   }
  59.  
  60.   // Получить координаты блока на картинке для нанесения надписи
  61.   switch ($watermark_position) {
  62.     case WATERMARK_LEFT_BOTTOM: {
  63.       $pos_x=10;
  64.       $pos_y=$sy-$my-10;
  65.       break;
  66.     }
  67.     case WATERMARK_RIGHT_BOTTOM: {
  68.       $pos_x=$sx-$mx-10;
  69.       $pos_y=$sy-$my-10;
  70.       break;
  71.     }
  72.     case WATERMARK_LEFT_TOP: {
  73.       $pos_x=10;
  74.       $pos_y=10;
  75.       break;
  76.     }
  77.     case WATERMARK_RIGHT_TOP: {
  78.       $pos_x=$sx-$mx-10;
  79.       $pos_y=10;
  80.       break;
  81.     }
  82.     case WATERMARK_CENTER: {
  83.       $pos_x=intval($sx/2-$mx/2);
  84.       $pos_y=intval($sy/2-$my/2);
  85.       break;
  86.     }
  87.     default: {
  88.       imageDestroy($im);
  89.       return false;
  90.     }
  91.   }
  92.  
  93.   // Нанести водяной знак с нужной прозрачностью
  94.   $watermark=@ImageCreateFromPng($marker);
  95.   ImageCopyMerge($im$watermark$pos_x$pos_y00$mx$my$opacity);     
  96.   ImageDestroy($watermark);
  97.  
  98.   // Записать измененный файл на место
  99.   switch (strtolower($pocket[1])) {
  100.     case "jpeg":
  101.     case "jpg": {
  102.       ImageJPEG($im,$picture,90);
  103.       break;
  104.     }
  105.     case "gif": {
  106.       ImageGIF($im,$picture);
  107.       break;
  108.     }
  109.     case "png": {
  110.       ImagePNG($im,$picture);
  111.       break;
  112.     }
  113.   }
  114.   ImageDestroy($im);
  115.   return true
  116. }
Параметры вызова функции: $picture - полный путь к файлу на сервере, поддерживаются форматы JPG, GIF, PNG. Файл должен быть доступен для записи, так как после нанесения водяного знака он будет перезаписан с тем же именем. $marker - полный путь к файлу водяного знака в формате PNG. $opacity - прозрачность водяного знака в процентах, необязательный параметр, по умолчанию 100%. $watermark_position - положение маркера на картинке, необязательный параметр, по умолчанию правый нижний угол изображения. Доступные значения определены константами, прочие значения игнорируются: 0 - левый нижний угол, 1 - левый верхний угол, 2 - правый нижний угол (значение по умолчанию), 3 - правый верхний угол, 4 - центр изображения.

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

Антиникотиновый информер

02.05.2009 | Категория: Web-мастеру и не только | Автор: ManHunter

Антиникотиновый информер

Когда я бросил курить, то в качестве стимула сделал себе такой антиникотиновый информер и использую его в подписи на некоторых форумах. Это PHP-скрипт, который считает в реальном времени сколько всего сэкономлено и выводит результат в виде графического файла.
  1. <?
  2. //-------------------------------------------------------------
  3. // Скрипт антиникотинового информера с интервалами дат
  4. // Copyright (C) ManHunter / PCL
  5. // http://www.manhunter.ru
  6. //-------------------------------------------------------------
  7.  
  8. // Настройки информера
  9. $cig_per_day=20;      // Сигарет в сутки, шт.
  10. $rub_per_day=65;      // Денег на сигареты в сутки, руб.
  11. $nikotin=1.2;         // Количество никотина в 1 сигарете, мг.
  12.  
  13. $d=28;                // Месяц, когда бросил курить
  14. $y=2008;              // Год, когда бросил курить
  15. $m=7;                 // День, когда бросил курить
  16.  
  17. $h=11;                // Время, когда бросил курить, часы
  18. $i=30;                // Время, когда бросил курить, минуты
  19.  
  20. $size=10;             // Размер шрифта информера
  21. $font="my_font.ttf";  // Файл с TTF-шрифтом
  22. $border=10;           // Отступ текста от границ
  23. //-------------------------------------------------------------
  24.  
  25. // Дальше лучше ничего без надобности не менять
  26.  
  27. function num2word($num,$words) {
  28.   $num=$num%100;
  29.   if ($num>19) { $num=$num%10; }
  30.   switch ($num) {
  31.     case 1:  { return($words[0]); }
  32.     case 2:
  33.     case 3:
  34.     case 4:  { return($words[1]); }
  35.     default: { return($words[2]); }
  36.   }
  37. }
  38.  
  39. $start_date=mktime($h,$i,0,$m,$d,$y);
  40. $end_date=time();
  41.  
  42. $day=intval(($end_date-$start_date)/(24*60*60));
  43. $hour=intval(($end_date-$start_date-$day*24*60*60)/(60*60));
  44.  
  45. $days_array=Array("день""дня""дней");
  46. $hour_array=Array("час""часа""часов");
  47.  
  48. // Сгенерировать текст информера
  49. $str="Не курю: ".$day." ".num2word($day,$days_array)." ".
  50.      ($hour==0?"ровно":$hour." ".num2word($hour,$hour_array))."\n".
  51.      "Не выкурено сигарет: ".
  52.      intval(($day+($hour/24))*$cig_per_day)." шт.\n".
  53.      "Не потрачено денег: ".
  54.      intval(($day+($hour/24))*$rub_per_day)." руб.\n".
  55.      "Не убито лошадок: ".
  56.      intval(($day+($hour/24))*$cig_per_day*$nikotin/50)." шт.";
  57.  
  58. // Перевести в юникод, чтобы корректно отображались русские буквы
  59. $str=iconv('windows-1251','utf-8',$str);
  60.  
  61. // Получить размер графического блока для вывода текста
  62. list($ldx,$ldy,$rdx,$rdy,$rux,$ruy,$lux,$luy)=imageTTFBBox($size,0,$font,$str);
  63.  
  64. // Получить размер информера
  65. $xx=$rdx+$border*2+$size;
  66. $yy=$rdy+$border*2+$size;
  67.  
  68. // Создать изображение
  69. $im=imageCreatetruecolor($xx,$yy);
  70.  
  71. // Определить цвета
  72. $black=imageColorAllocate($im,0,0,0);
  73. $red=imageColorAllocate($im,255,0,0);
  74. $white=imageColorAllocate($im,255,255,255);
  75.  
  76. // Белый прямоугольник с красной рамкой
  77. ImageFilledRectangle($im,0,0,$xx,$yy,$red);
  78. ImageFilledRectangle($im,1,1,($xx-2),($yy-2),$white);
  79.  
  80. // Наложить текст на фон
  81. imagettftext($im,$size,0,$border+5,$border+$size,$black,$font,$str);
  82.  
  83. // Вывести картинку в формате PNG
  84. Header("Content-type: image/png");
  85. imagePNG($im);
  86. ?>
В этом примере в скрипт занесены данные: одна пачка сигарет в день, средняя цена пачки - 65 рублей (я курил "Captain Black") и содержание никотина 1,2 мг в 1 сигарете. Расчет лошадок выполняется на основании фразы "капля никотина убивает лошадь" и данных, что 1 капля никотина весит примерно 50 мг. Файл с кириллическим TrueType-шрифтом my_font.ttf должен находиться в той же папке, где размещен скрипт. PHP должен быть собран с поддержкой графической библиотеки GD2.

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

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

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 - центр изображения.

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

01 ... 08 09 10 11 12 13 14 15 16 next
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.12 сек. / MySQL: 3 (0.0548 сек.) / Память: 4.75 Mb
Наверх