5 вариантов добавления watermark (водяной знак) на изображение, средствами PHP

Author Роман Чернышов    Category PHP     Tags , Комментариев 0 Дата 11 Май

watermark 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”);

В заключении, хочется сказать, что все примеры по своему хороши. Некоторые подойдут и для крупных проектов, другие же выручат того, когда все нужно сделать быстро не тратя время на разборы. Надеюсь вам будет полезен данный пост.

Оставить комментарий

О блоге и авторе

Добро пожаловать на блог веб-разработчика! На протяжении многих лет, начиная с 2009 года, я занимаюсь созданием специализированных сайтов, сервисов и крупных веб-порталов. Мною было создано несколько сотен сайтов, большинство из которых работают на ПО созданном под заказ, а также на готовом ПО которое я разрабатываю на протяжении всего периода моей деятельности. Это: CMS "Совместные покупки", CMS "osRealty", CMS "Спорт прогнозы" и многое другое.

На страницах моего блога вы найдете множество информации о программировании, о появлении новых разработок, сможете ознакомиться с товарами и услугами которые я предоставляю. А также сможете получить консультацию, заказать разработку сайта или приобрести готовое решение, для реализации собственного проекта.

Поиск по блогу
Категории
Архив
Новое на сайте
Блогеры пишут
  • Роман Чернышов: Для работы капчи на PHP 5.6, замените в файле class.captcha.php строку 264 $ifunc( $this -> i [...]
  • Роман Чернышов: Схема такая: 1) На сайте есть виртуальные кошельки (далее ВК) 2) При пополнении пользователем ВК, [...]
  • Александр: Может скрипт комментариев блокирует сообщения с кодом? Или как длинный текст не проходит?
  • Александр: Пытаюсь в который раз здесь показать код, но страница обновляется, и не сообщения, ни любого оповеще [...]
  • Роман Чернышов: Лично у меня интерес к продаже ссылок пропал уже давно. Преимущество сапы, это то - что ссылки можно [...]
Портфолио Все работы

www.detskiy-mir.net
www.detskydoctor.ru
www.betelit.ru
www.all-alliance.ru
www.videogonok.ru
www.carpfishing.by
www.property-greek.com
www.domcons.ru

с 2009 года по сегодняшний день, создано более 300 сайтов...