Водяные знаки (watermarks) — это не хитрый приём, который используют на многих сайтах, чтобы избежать «утечки» картинок. Суть проста — на картинки контент области (публикаций сайта) производят наложение логотипа или надписи с названием сайта и т.п. Разместить такую картинку на другом сайте можно и после этой операции, но, наверное, ясно, что это позволят себе только те, кому на коммерческую сторону вопроса наплевать — т.е. в этот круг ваши конкуренты не попадают. Кроме того, это уже будет дополнительной рекламой вашего сайта.
Движков сейчас очень много. Задача давно решена и везде по-разному, часто зависит от программной архитектуры . Мой подход к этому вопросу, возможно, покажется своеобразным. Давайте напишем надстройку, которая принципиально подойдет к любому движку.
Стартовые условия следующие:
1. Веб-сервер — apache;
2. Сервер умеет выполнять php скрипты;
3. Контент-картинки сгруппированы в какой то одной или нескольких папках (возможно с подпапками);
4. Для php установлена библиотека работы с графикой (иначе можно рассмотреть ещё использование imagemagic)
Идея состоит в следующем. Есть папки, содержащие файлы картинок. Обычно это папки, куда сохраняются картинки при редактировании публикаций CMS данного сайта. К примеру, в wordpress это wp-content/uploads, а в drupal что то вроде sites/default/files. Место зависит конечно же от настроек и движка. Мы будем перехватывать обращения к файлам в таких папках, смотреть, что это за файлы и, если это картинки, будем накладывать на них водяные знаки перед тем как выдать их по текущему запросу.
Для этого в файл .htaccess в папке, где лежат картинки, добавим (или создадим такой файл, если его не было там) примерно такие инструкции:
1 2 3 |
RewriteEngine On RewriteCond %{REQUEST_FILENAME} -f RewriteRule . /watermark/watermark.php [L] |
Это позволяет вместо прямой выдачи файлов, выполнить PHP скрипт (в нашем случае это /watermark/watermark.php). Данный скрипт должен выдать картинку с наложенными на неё водяными знаками. На следующем листинге приведу пример такого скрипта (он вполне рабочий, его также можно взять за основу для вашего случая).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
//это константа должна содержать путь до корневого каталога сайта на сервере DEFINE ('MAINDIR', $_SERVER['DOCUMENT_ROOT'].'/'); //органичим общий перечень файлов по расширению //файлы с прочими расширениями - выдавать не будем (только из соображений безопасности) if (!preg_match('#\.(jpeg|jpg|jpe|gif|bmp|png|xls|doc|zip|rar|pdf)$#iU', $_SERVER["REQUEST_URI"])) { header('HTTP/1.1 403 Access denied'); exit; } //это полный путь до запрашиваемого файла $filename = $_SERVER['DOCUMENT_ROOT'] . urldecode($_SERVER["REQUEST_URI"]); //если такого файла нет на сервере, действовать можно по-разному //1. выдать ошибку 404 - header('HTTP/1.1 403 Access denied'); //2. выдать какой то файл по умолчанию //в данном случае, я выдаю файл нулевой длины с названием nofile if (!file_exists($filename)) { header('Content-Type: application/download'); header('Content-Length: 0'); header('Content-Disposition: attachment; filename="nofile"'); exit; } //наш файл, судя по расширению, картинка - добавим водяной знак if (preg_match('#\.(jpeg|jpg|jpe|gif|png)$#iU', $_SERVER["REQUEST_URI"], $m)) { header("Content-Type: image/$m[1]; charset=utf-8"); header('Content-Disposition: attachment; filename="'. basename($filename) . '"'); $im = GetImageSize($filename); //если тип изображения определен (gif, jpeg или png) и картинка по высоте > 100 пикс //я исключаю небольшие по высоте картинки из обработки, потому что обычно водяные знаки на //на них смотрятся не очень приятно if ($im[2] && $im[1] > 100) { $a = 0; switch ($im[2]) { case 1: $a = ImageCreateFromGIF($filename); break; case 2: $a = ImageCreateFromJPEG($filename); break; case 3: $a = ImageCreateFromPNG($filename); break; } if ($a) { //добавление водяных знаков. накладываю картинку водяных знаков в виде //полупрозрачной горизонтальной ленточки через всю картинку чуть ниже центра. //так как наложение производится путем сложения (imagecopymerge), то прозрачные //участки картинки должны быть выполнены черным цветом (RGB код - #000000) $filename_wm = MAINDIR . 'watermark/ac66copyrights.gif'; $im_wm = GetImageSize($filename_wm); $posY_wm = (int) $im[1] * 0.6; $posX_wm = 0; $b = ImageCreateFromGIF($filename_wm); imagealphablending($b, true); while ($posX_wm < $im[0]) { imagecopymerge($a, $b, $posX_wm, $posY_wm, 0, 0, $im_wm[0], $im_wm[1], 20); $posX_wm += $im_wm[0]; } imagedestroy($b); //выдаём готовое изображение. switch ($im[2]) { case 1: imagegif($a); break; case 2: imagejpeg($a); break; case 3: imagepng($a); break; } //уничтожаем ресурсы imagedestroy($a); exit; } } //случай маленькой картинки или неопознанного формата картинки readfile($filename); exit; } else { //другие файлы (не картинки) header('Content-Type: application/download; charset=utf-8'); header('Content-Disposition: attachment; filename="'. basename($filename) . '"'); header('Content-Length: ' . filesize($filename)); readfile($filename); exit; } |
Код довольно короткий, и имеет как плюсы так и недостатки.
На практике, да ещё и при достаточно высокой нагрузке на сервер, стоит добавить кеширование результатов обработки картинок. Я намерено не стал этого делать, чтобы не загружать листинг лишним в нашей теме кодом. Если не заботится об оптимизации, то программу можно использовать и в таком виде.
Код, как я и заявлял в начале, не зависит от того, какой движок используется сайтом. При желании и умении, можно выполнить этот код в виде модуля к соответствующему движку.
Здравствуйте!
пришла к вам с друпал.ру, вы там ссылку давали
подскажите пожалуйста,а можно сделать так что бы ватермарк накладывался только на новые картинки при их загрузке и его можно было отключить в отдельных случаях
заранее спасибо
Этот скрипт, как раз позволяет делать такие вещи. В вашем случае можно сделать пару папок — и в одну грузить картинки на сайт, которым нужны WM, а в другую которым они не нужны. В ту папку, где картинки требуют наложения WM, добавить файл .htaccess с указанными инструкциями. Т.е. задача сводится к правильному размещению инструкций для сервера apache.
А вариантом с кешированием не поделитесь?
У меня нет готового варианта, где добавлено только кеширование результата, есть более сложный вариант, с попутным созданием миниатюр, наложением водяного знака и сохранением картинки (т.е. собственно с созданием кеша). Скрипт использует данные CMS о типах разрешенных миниатюр, и пример будет не универсальным относительно используемой CMS. Едва ли будет полезен Вам.