3 способа добавить watermark (водяной знак) на изображение — php

Сентябрь 25, 2007

Немного порылся в своих старых проектах, нашел целых три способа, как я в свое время реализовывал добавление водяного знака на картинки.

Первое, что хотелось бы сказать: сохраняйте классы и функции, велосипед — это клево, но несколько раз — слишком (в моем случае дело упрощает то, что один из них — трехколесный, еще один — чужой).

Второе: опишу по-подробнее, что да как:

Исходные данные:

замечательный рисунок работы Вила Мюрэя:

прозрачный png8:

прозрачный png24:

И какой-нибудь файл шрифта ttf.

Способ №1

Вывод по диагонали строки на изображение.


class watermark1
{
  function create_watermark( $main_img_obj, $text, $font, $r = 128, $g = 128, $b = 128, $alpha_level = 100 )
  {
   $width = imagesx($main_img_obj);
   $height = imagesy($main_img_obj);
   $angle =  -rad2deg(atan2((-$height),($width)));

   $text = " ".$text." ";

   $c = imagecolorallocatealpha($main_img_obj, $r, $g, $b, $alpha_level);
   $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($main_img_obj,$size ,$angle, $x, $y, $c, $font, $text);
   return $main_img_obj;
  }
}

$main_img_obj — идентификатор изображения, на которое добавляется надпись

$text — текст надписи

$font — имя файла шрифта .ttf

$r,$g,$b — цвет надписи

$alpha_level — прозрачность (0 — не прозрачная, 128 — полностью прозрачная)

Вызываем:

$watermark = new watermark1();
$img = imagecreatefromjpeg(«image.jpg»);
$im=$watermark->create_watermark($img,»jeka911.wordpress.com»,»1.ttf»,0,0,255,120);
imagejpeg($im,»result.jpg»);

Получаем:

Все просчеты в функции получены методом тыка, так что не бойтесь экспериментировать.

Способ №2

Добавление в качестве вотермарка 8-битного png


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;
}
}

$main_img_obj — идентификатор изображения, на которое добавляется надпись

$watermark_img_obj — ид. изображения прозрачного png8

$alpha_level — прозрачность (0 — прозрачное, 100 — полностью непрозрачное)

Вызываем:

$watermark = new watermark2();
$img = imagecreatefromjpeg(«image.jpg»);
$water = imagecreatefrompng(«watermark8.png»);
$im=$watermark->create_watermark($img,$water,10);
imagejpeg($im,»result.jpg»);

Получаем:

Способ №3

Добавление водяным знаком 24х битного png (видимо, брал отсюда)


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()

} # END watermark API

$main_img_obj — идентификатор изображения, на которое добавляется надпись

$watermark_img_obj — ид. изображения прозрачного png8

$alpha_level — прозрачность (0 — прозрачное, 100 — полностью непрозрачное)

Вызываем:

$watermark = new watermark3();
$img = imagecreatefromjpeg(«image.jpg»);
$water = imagecreatefrompng(«watermark24.png»);
$im=$watermark->create_watermark($img,$water,10);
imagejpeg($im,»result.jpg»);

Получаем:

Спасибо за внимание.

RSS

Реклама

imagegrabwindow

Сентябрь 19, 2007

Вот какая мощная функция есть в >= 5.2.2 под виндой

imagegrabwindow — делает скриншот окна приложения. возвращает идентификатор изображения или false при неудачной попытке.

$browser = new COM("InternetExplorer.Application");
$handle = $browser->HWND;
$browser->Visible = true;
$browser->Navigate("https://jeka911.wordpress.com");

/* Still working? */
while ($browser->Busy) {
com_message_pump(4000);
}
$im = imagegrabwindow($handle, 0);
$browser->Quit();
imagepng($im, "iesnap.png");

И получается скриншот сайта с php.

Опа, какой мощный комментарий от nopox’a:

Первый нах! :)

Субъективное мнение: COM суть зло, ибо неуниверсально и привязано к платформе. Хотя, с другой стороны, эта задача — автоматизированное создание скриншотов сайта — не имеет красивых решений.

Вообще, если кому вдруг понадобится куча скриншотов: для Windows можно использовать утилиту url2bmp (http://www.pixel-technology.com/freeware/url2bmp), которая помимо графического имеет мощный консольный интерфейс.

Для Unix придётся устанавливать X-server, запускать браузер и делать снимок окна посредством import из ImageMagick.

Вообще, наверное, надо взяться и написать универсальный интерфейс, максимально упрощающий и унифицирующий процедуру создания скринов сайта :)


Image Tag Cloud (Облако картинок)

Август 29, 2007

Русскоязычный вордпрессВот к чему был предыдущий пост (не, я не пытался нагонять интригу, я просто доделывал).

Мой друг Romiz пару раз подгонял мне идею про, так называемое, облако картинок. Т.е. как облако тэгов, только вместо слов — изображения.

Думал немного на эту тему, попадались то ужасные, то интересные экземпляры. Решил сам поэкспериментировать. Результаты, конечно, далеки от совершенства, но все же.

Итак:

  • phpImageCloud — главная страница
  • Static demo — картинка из предыдущего поста, только рабочая
  • Client-side demo — это опять таки по напрягу Romiz’а, анимация с jquery. Попробуйте, выгребать свой блог из кучи соседей — довольно занятное дело, имхо.

Все чуствует себя GNU GPL, живет на sourceforge (кстати, еще один мастевой способ меньше переживать за жесткие диски).

Скачать, если кому интересно.


Когда сервер плохо настроен

Август 12, 2007

Видели когда нибудь код главной страницы Facebook? Посмотрите.

via


Вопросы ублюдочности…

Июль 20, 2007

Вот читаю такое и думаю: «бля, а ведь на моей стиральной машине не стоит дотнет!!!».


Выиграй ZendStudio

Июль 19, 2007

Пацаны из Zend’а просят написать им 30-150 строк кода, который бы красиво демонстрировал подсветку синтаксиса и дебагинг. подробнее


Кто без аякса? [updated]

Июль 17, 2007

Проверить, запрашивает ли клиент скрипт через аякс можно так:

if($_SERVER[«HTTP_X_REQUESTED_WITH»] == ‘XMLHttpRequest’)
{

echo «Привет, аякс!»;

}

else die(«Кiна не буде, кiношник у аппарат нассяв :( «);

Update from Miracle: С популярными фреймворками оно так просто и есть (jquery, prototype …), а иначе этот кусок в хидер нужно добавлять самому