5 вариантов добавления watermark (водяной знак) на изображение, средствами PHP
Данный пост содержит пять примеров, вариантов, добавления водяного знака на изображение с помощью PHP. Думаю о пользе добавления watermark’а все в курсе, в первую очередь это своеобразная защита изображения от несанкционированного копирования его и последующее использование на других сайтах. Во вторых, добавление ненавязчивого водяного знака это хороший способ лишний раз прорекламировать свой сайт(бренд, фирму) пользователю, который не всегда читает текст, но всегда смотрит картинки.
Все примеры, скрипты использовались мною в разных проектах, часть их была найдена в сети, что-то было существенно переделано, что-то оставлено без изменений.
И так приступим.
Пример 1. Данный весьма простой скрипт можно отнести к официальным примерам, он размещен на php.net. Все предельно просто. на одно изображение накладывается другое (PNG с прозрачностью).
// Загрузка штампа и фото, для которого применяется водяной знак (называется штамп или печать) $stamp = imagecreatefrompng('stamp.png'); $im = imagecreatefromjpeg('photo.jpeg'); // Установка полей для штампа и получение высоты/ширины штампа $marge_right = 10; $marge_bottom = 10; $sx = imagesx($stamp); $sy = imagesy($stamp); // Копирование изображения штампа на фотографию с помощью смещения края // и ширины фотографии для расчета позиционирования штампа. imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp)); // Вывод и освобождение памяти header('Content-type: image/png'); imagepng($im); imagedestroy($im); |
Пример 2. Более удобен в использовании, т.к. представляет из себя функцию. Пример показывает как можно добавить watermark, просто написав нужный текст на изображении.
function add_watermark($img, $text, $font, $r = 128, $g = 128, $b = 128, $alpha = 100) { //получаем ширину и высоту исходного изображения $width = imagesx($img); $height = imagesy($img); //угол поворота текста $angle = -rad2deg(atan2((-$height),($width))); //добавляем пробелы к строке $text = " ".$text." "; $c = imagecolorallocatealpha($img, $r, $g, $b, $alpha); $size = (($width+$height)/2)*2/strlen($text); $box = imagettfbbox ( $size, $angle, $font, $text ); $x = $width/2 - abs($box[4] - $box[0])/2; $y = $height/2 + abs($box[5] - $box[1])/2; //записываем строку на изображение imagettftext($img,$size ,$angle, $x, $y, $c, $font, $text); return $img; } |
Параметры функции следующие
$img – идентификатор изображения, на которое добавляется водяной знак
$text – текст надписи
$font – имя файла шрифта .ttf
$r,$g,$b – цвет надписи в формате RGB
$alpha – уровень прозрачности , от 0 до 128
Пример вызова функции:
$img = imagecreatefromjpeg('elbrus.jpg'); $image = add_watermark($img2,'Grigorieff.ru','erasbd.ttf'); //выводим изображение imageJPEG($image); //освобождаем память imagedestroy($image); imagedestroy($img2); |
Пример 3. Не плохая функция, но работает с глобальной переменной хранящей адрес изображения которое будет накладываться на исходное (адрес watermark’а). Вариант на любителя.
/** * Наложение водяного знака в виде изображения * @param $oldimage_name - исходное изображение * @param $new_image_name - выходное изображение * @return Boolean */ function watermark_image($oldimage_name, $new_image_name){ // получаем имя изображения, используемого в качестве водяного знака global $image_path; // получаем размеры исходного изображения list($owidth,$oheight) = getimagesize($oldimage_name); // задаем размеры для выходного изображения $width = 600; $height = 300; // создаем выходное изображение размерами, указанными выше $im = imagecreatetruecolor($width, $height); $img_src = imagecreatefromjpeg($oldimage_name); // наложение на выходное изображение, исходного imagecopyresampled($im, $img_src, 0, 0, 0, 0, $width, $height, $owidth, $oheight); $watermark = imagecreatefrompng($image_path); // получаем размеры водяного знака list($w_width, $w_height) = getimagesize($image_path); // определяем позицию расположения водяного знака $pos_x = $width - $w_width; $pos_y = $height - $w_height; // накладываем водяной знак imagecopy($im, $watermark, $pos_x, $pos_y, 0, 0, $w_width, $w_height); // сохраняем выходное изображение, уже с водяным знаком в формате jpg и качеством 100 imagejpeg($im, $new_image_name, 100); // уничтожаем изображения imagedestroy($im); unlink($oldimage_name); return true; } |
Пример 4. Пример добавление водяного знака из 8 битного PNG файла. Оформлен в класс (автор посчитал это забавным).
/* * @param $main_img_obj – идентификатор изображения, на которое добавляется надпись * @param $watermark_img_obj – ид. изображения прозрачного png8 * @param $alpha_level – прозрачность (0 – прозрачное, 100 – полностью непрозрачное) * @return $main_img_obj - указатель изображения */ class watermark2 { function create_watermark( $main_img_obj, $watermark_img_obj, $alpha_level = 100 ) { $watermark_width = imagesx($watermark_img_obj); $watermark_height = imagesy($watermark_img_obj); $dest_x = imagesx($main_img_obj) - $watermark_width - 5; $dest_y = imagesy($main_img_obj) - $watermark_height - 5; imagecopymerge($main_img_obj, $watermark_img_obj, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $alpha_level); return $main_img_obj; } } |
Пример вызова функции:
$watermark = new watermark2(); $img = imagecreatefromjpeg(“image.jpg”); $water = imagecreatefrompng(“watermark8.png”); $im=$watermark->create_watermark($img,$water,10); imagejpeg($im,”result.jpg”); |
Пример 5. Самый интересный пример, оформлен в PHP класс. Работает в PNG 24. есть возможность настройки параметров прозрачности. В интернетах этот вариант выкладывали и обсуждали не раз.
/* * @param $main_img_obj – идентификатор изображения, на которое добавляется надпись * @param $watermark_img_obj – ид. изображения прозрачного png8 * @param $alpha_level – прозрачность (0 – прозрачное, 100 – полностью непрозрачное) * @return $main_img_obj - указатель изображения */ class watermark3{ # given two images, return a blended watermarked image function create_watermark( $main_img_obj, $watermark_img_obj, $alpha_level = 100 ) { $alpha_level /= 100; # convert 0-100 (%) alpha to decimal # calculate our images dimensions $main_img_obj_w = imagesx( $main_img_obj ); $main_img_obj_h = imagesy( $main_img_obj ); $watermark_img_obj_w = imagesx( $watermark_img_obj ); $watermark_img_obj_h = imagesy( $watermark_img_obj ); # determine center position coordinates $main_img_obj_min_x = floor( ( $main_img_obj_w / 2 ) - ( $watermark_img_obj_w / 2 ) ); $main_img_obj_max_x = ceil( ( $main_img_obj_w / 2 ) + ( $watermark_img_obj_w / 2 ) ); $main_img_obj_min_y = floor( ( $main_img_obj_h / 2 ) - ( $watermark_img_obj_h / 2 ) ); $main_img_obj_max_y = ceil( ( $main_img_obj_h / 2 ) + ( $watermark_img_obj_h / 2 ) ); # create new image to hold merged changes $return_img = imagecreatetruecolor( $main_img_obj_w, $main_img_obj_h ); # walk through main image for( $y = 0; $y < $main_img_obj_h; $y++ ) { for( $x = 0; $x < $main_img_obj_w; $x++ ) { $return_color = NULL; # determine the correct pixel location within our watermark $watermark_x = $x - $main_img_obj_min_x; $watermark_y = $y - $main_img_obj_min_y; # fetch color information for both of our images $main_rgb = imagecolorsforindex( $main_img_obj, imagecolorat( $main_img_obj, $x, $y ) ); # if our watermark has a non-transparent value at this pixel intersection # and we're still within the bounds of the watermark image if ( $watermark_x >= 0 && $watermark_x < $watermark_img_obj_w && $watermark_y >= 0 && $watermark_y < $watermark_img_obj_h ) { $watermark_rbg = imagecolorsforindex( $watermark_img_obj, imagecolorat( $watermark_img_obj, $watermark_x, $watermark_y ) ); # using image alpha, and user specified alpha, calculate average $watermark_alpha = round( ( ( 127 - $watermark_rbg['alpha'] ) / 127 ), 2 ); $watermark_alpha = $watermark_alpha * $alpha_level; # calculate the color 'average' between the two - taking into account the specified alpha level $avg_red = $this->_get_ave_color( $main_rgb['red'], $watermark_rbg['red'], $watermark_alpha ); $avg_green = $this->_get_ave_color( $main_rgb['green'], $watermark_rbg['green'], $watermark_alpha ); $avg_blue = $this->_get_ave_color( $main_rgb['blue'], $watermark_rbg['blue'], $watermark_alpha ); # calculate a color index value using the average RGB values we've determined $return_color = $this->_get_image_color( $return_img, $avg_red, $avg_green, $avg_blue ); # if we're not dealing with an average color here, then let's just copy over the main color } else { $return_color = imagecolorat( $main_img_obj, $x, $y ); } # END if watermark # draw the appropriate color onto the return image imagesetpixel( $return_img, $x, $y, $return_color ); } # END for each X pixel } # END for each Y pixel # return the resulting, watermarked image for display return $return_img; } # END create_watermark() # average two colors given an alpha function _get_ave_color( $color_a, $color_b, $alpha_level ) { return round( ( ( $color_a * ( 1 - $alpha_level ) ) + ( $color_b * $alpha_level ) ) ); } # END _get_ave_color() # return closest pallette-color match for RGB values function _get_image_color($im, $r, $g, $b) { $c=imagecolorexact($im, $r, $g, $b); if ($c!=-1) return $c; $c=imagecolorallocate($im, $r, $g, $b); if ($c!=-1) return $c; return imagecolorclosest($im, $r, $g, $b); } # EBD _get_image_color() } |
Пример вызова функции:
$watermark = new watermark3(); $img = imagecreatefromjpeg(“image.jpg”); $water = imagecreatefrompng(“watermark24.png”); $im=$watermark->create_watermark($img,$water,10); imagejpeg($im,”result.jpg”); |
В заключении, хочется сказать, что все примеры по своему хороши. Некоторые подойдут и для крупных проектов, другие же выручат того, когда все нужно сделать быстро не тратя время на разборы. Надеюсь вам будет полезен данный пост.
Похожие записи
5 комментариев to “5 вариантов добавления watermark (водяной знак) на изображение, средствами PHP”
Оставить комментарий
Full Stack
Senior, Architect
предложить оффер
- jQuery: как получить значение атрибута?
- PHP работа с изображением, класс SimpleImage
- Интеграция с API ОСАГО сайта sravni.ru
- Комментарии на PHP, Ajax, mySQL
- PHP: Категории бесконечного уровня вложенности.
- Nginx редирект на другой сервис с сохранением URL спросил (а) Сергей
- Исполнитель пропал, почему такое случается и понять с кем работать? спросил (а) Артем
- Можно ли WordPress считать универсальным движком? спросил (а) Андрей
- Что такое самописный скрипт или CMS? спросил (а) Антон
- Как при поиске в linux используя grep, добавить исключения? спросил (а) Алексей
- Консольный скрипт(JavaScript) для автоматических заказов на OZON к записи
- Консольный скрипт(JavaScript) для автоматических заказов на OZON к записи
- Как создать Telegram-бота с авторизацией через сайт к записи
- PHP скрипт: каталог закладок на сайты к записи
- Валидация на PHP к записи
- Сколько зарабатывают в бизнесе на совместных покупках к записи
- Сколько зарабатывают в бизнесе на совместных покупках к записи
Archive
- +2024 (25)
- Ноябрь 2024 (10)
- Октябрь 2024 (8)
- Сентябрь 2024 (1)
- Август 2024 (5)
- Май 2024 (1)
- +2023 (27)
- Ноябрь 2023 (1)
- Октябрь 2023 (13)
- Сентябрь 2023 (10)
- Апрель 2023 (1)
- Март 2023 (1)
- Февраль 2023 (1)
- +2022 (21)
- Декабрь 2022 (11)
- Ноябрь 2022 (1)
- Май 2022 (2)
- Апрель 2022 (2)
- Март 2022 (3)
- Февраль 2022 (1)
- Январь 2022 (1)
- +2021 (17)
- Декабрь 2021 (5)
- Ноябрь 2021 (2)
- Июль 2021 (1)
- Июнь 2021 (2)
- Май 2021 (5)
- Апрель 2021 (1)
- Март 2021 (1)
- +2020 (20)
- Декабрь 2020 (6)
- Сентябрь 2020 (2)
- Август 2020 (1)
- Июль 2020 (2)
- Май 2020 (2)
- Апрель 2020 (2)
- Март 2020 (2)
- Февраль 2020 (1)
- Январь 2020 (2)
- +2019 (18)
- Декабрь 2019 (3)
- Ноябрь 2019 (2)
- Октябрь 2019 (2)
- Сентябрь 2019 (1)
- Август 2019 (2)
- Июль 2019 (1)
- Июнь 2019 (1)
- Апрель 2019 (2)
- Март 2019 (1)
- Февраль 2019 (3)
- +2018 (44)
- Декабрь 2018 (4)
- Ноябрь 2018 (7)
- Октябрь 2018 (8)
- Сентябрь 2018 (1)
- Август 2018 (4)
- Июль 2018 (5)
- Май 2018 (3)
- Апрель 2018 (7)
- Март 2018 (1)
- Февраль 2018 (2)
- Январь 2018 (2)
- +2017 (19)
- Декабрь 2017 (2)
- Ноябрь 2017 (1)
- Октябрь 2017 (1)
- Сентябрь 2017 (2)
- Июль 2017 (1)
- Июнь 2017 (1)
- Май 2017 (2)
- Апрель 2017 (3)
- Март 2017 (2)
- Февраль 2017 (1)
- Январь 2017 (3)
- +2016 (36)
- Декабрь 2016 (3)
- Ноябрь 2016 (3)
- Октябрь 2016 (2)
- Сентябрь 2016 (3)
- Август 2016 (7)
- Июнь 2016 (3)
- Май 2016 (3)
- Апрель 2016 (3)
- Февраль 2016 (1)
- Январь 2016 (8)
- +2015 (36)
- Ноябрь 2015 (5)
- Октябрь 2015 (4)
- Сентябрь 2015 (1)
- Август 2015 (8)
- Июнь 2015 (1)
- Май 2015 (4)
- Апрель 2015 (8)
- Март 2015 (3)
- Февраль 2015 (2)
- +2014 (26)
- Ноябрь 2014 (2)
- Октябрь 2014 (5)
- Сентябрь 2014 (6)
- Июль 2014 (1)
- Июнь 2014 (2)
- Май 2014 (3)
- Апрель 2014 (6)
- Февраль 2014 (1)
- +2013 (27)
- Декабрь 2013 (2)
- Ноябрь 2013 (1)
- Октябрь 2013 (1)
- Август 2013 (1)
- Июль 2013 (3)
- Июнь 2013 (10)
- Май 2013 (1)
- Апрель 2013 (2)
- Февраль 2013 (3)
- Январь 2013 (3)
- +2012 (41)
- Декабрь 2012 (2)
- Ноябрь 2012 (3)
- Октябрь 2012 (7)
- Сентябрь 2012 (2)
- Август 2012 (1)
- Июль 2012 (3)
- Июнь 2012 (2)
- Май 2012 (6)
- Апрель 2012 (2)
- Март 2012 (7)
- Февраль 2012 (5)
- Январь 2012 (1)
- +2011 (57)
- Декабрь 2011 (6)
- Ноябрь 2011 (2)
- Октябрь 2011 (3)
- Сентябрь 2011 (5)
- Август 2011 (4)
- Июль 2011 (3)
- Июнь 2011 (3)
- Май 2011 (3)
- Апрель 2011 (4)
- Март 2011 (10)
- Февраль 2011 (5)
- Январь 2011 (9)
- +2010 (43)
- Декабрь 2010 (7)
- Ноябрь 2010 (21)
- Октябрь 2010 (14)
- Сентябрь 2010 (1)
Свежие записи
- Интеграция платежной системы MoonPay на сайт по API 10.11.2024
- Парсер товаров с Taobao 08.11.2024
- Упаковка и минификация кода JavaScript онлайн 07.11.2024
- Как эффективно анализировать логи при DDOS атаке 07.11.2024
- Бот для автоматических заказов на OZON (плагин для Chrome) 07.11.2024
Подскажите, пожалуйста, а как разместить текст водяного знака ровно по горизонтали и в правом нижнем углу. Спасибо.
Заменить строки:
# determine center position coordinates
$main_img_obj_min_x = floor( ( $main_img_obj_w / 2 ) — ( $watermark_img_obj_w / 2 ) );
$main_img_obj_max_x = ceil( ( $main_img_obj_w / 2 ) + ( $watermark_img_obj_w / 2 ) );
$main_img_obj_min_y = floor( ( $main_img_obj_h / 2 ) — ( $watermark_img_obj_h / 2 ) );
$main_img_obj_max_y = ceil( ( $main_img_obj_h / 2 ) + ( $watermark_img_obj_h / 2 ) );
На:
# determine center position coordinates
$main_img_obj_min_x = $main_img_obj_w — 20 — $watermark_img_obj_w;
$main_img_obj_max_x = $main_img_obj_w — 20;
$main_img_obj_min_y = $main_img_obj_h — 20 — $watermark_img_obj_h;
$main_img_obj_max_y = $main_img_obj_h — 20;
Подскажите пожалуйста, как в такой конструкции
if ($width_orig != $width || $height_orig != $height) {
$image = new Image(DIR_IMAGE . $image_old);
$image->resize($width, $height);
$image->watermark(new Image(DIR_IMAGE . ‘watermark.png’), ‘bottomright’);
$image->save(DIR_IMAGE . $image_new);
} else {
copy(DIR_IMAGE . $image_old, DIR_IMAGE . $image_new);
}
указать размер watermark не более 50% от ширины картинки на которую он накладывается?
И можно ли сделать отступ снизу 20%?
Добрый день, для такого наложения необходима еще одна функция преобразования, а именно изменения размера накладываемого изображения — ресайз. Параметры ресайза можно высчитать на основании размера основного изображения. Вот мой пост про данную функцию(ресайз) с примером кода: https://rche.ru/1042_php-izmenenie-razmera-izobrazheniya-thumbnail.html
Благодарю за ответ! Пошел другим путем, нашел модуль готовый.