В этой статье я опишу как расширить класс JImage для возможности модифицировать

И так для того что бы мы могли накладывать водный знак на изображение, нам нужно унаследоваться от класса JImage и добавить четыре метода: loadWatermarkFilek(), getWidthWatermark(), getHeightWatermark(), applyWatermark()

Первые три метода это небольшая модификация стандартных методов класса JImage: loadFile(), getWidth(), getHeigh(). Но они служат для того что бы загружать файл водного знака и получать его ширину и высоту!

Итак код самого класса:

defined( '_JEXEC' ) or die;
Class Watermark extends JImage
{
	/**
	 * @var resource
	 * @since version 1.0
	 */
	private $watermark;

	/**
	 * Загрузка файла водного знака
	 * @param $path
	 * @throws RuntimeException
	 * @throws InvalidArgumentException
	 * @since version 1.0
	 */
	public function loadWatermarkFile( $path )
	{
		if ( !file_exists( $path ) ) {
			throw new InvalidArgumentException( 'The image file does not exist.' );
		}
		$properties = self::getImageFileProperties( $path );
		switch ( $properties->mime ) {
			case 'image/gif':
				// Make sure the image type is supported.
				if ( empty( self::$formats[IMAGETYPE_GIF] ) ) {
					// @codeCoverageIgnoreStart
					JLog::add( 'Attempting to load an image of unsupported type GIF.', JLog::ERROR );
					throw new RuntimeException( 'Attempting to load an image of unsupported type GIF.' );
				}
				$handle = imagecreatefromgif( $path );
				if ( !is_resource( $handle ) ) {
					throw new RuntimeException( 'Unable to process GIF image.' );
				}
				$this->watermark = $handle;
				break;
			case 'image/jpeg':
				if ( empty( self::$formats[IMAGETYPE_JPEG] ) ) {
					JLog::add( 'Attempting to load an image of unsupported type JPG.', JLog::ERROR );
					throw new RuntimeException( 'Attempting to load an image of unsupported type JPG.' );
				}
				$handle = imagecreatefromjpeg( $path );
				if ( !is_resource( $handle ) ) {
					// @codeCoverageIgnoreStart
					throw new RuntimeException( 'Unable to process JPG image.' );
				}
				$this->watermark = $handle;
				break;

			case 'image/png':
				if ( empty( self::$formats[IMAGETYPE_PNG] ) ) {
					JLog::add( 'Attempting to load an image of unsupported type PNG.', JLog::ERROR );
					throw new RuntimeException( 'Attempting to load an image of unsupported type PNG.' );
				}
				$handle = imagecreatefrompng( $path );
				if ( !is_resource( $handle ) ) {
					throw new RuntimeException( 'Unable to process PNG image.' );
				}
				$this->watermark = $handle;
				break;

			default:
				JLog::add( 'Attempting to load an image of unsupported type: ' . $properties->mime, JLog::ERROR );
				throw new InvalidArgumentException( 'Attempting to load an image of unsupported type: ' . $properties->mime );
				break;
		}

	}


	/**
	 * Метод выполняющий наложение водного знака
	 * @param int $vertical
	 * @param int $horizontal
	 * @since version 1.0
	 */
	public function applyWatermark( $vertical = 0, $horizontal = 0 )
	{

		$width = $this->getWidthWatermark();
		$height = $this->getHeightWatermark();
		$positionX = $horizontal == 0 ? $this->getWidth() - $width : 0;
		$positionY = $vertical == 0 ? $this->getHeight() - $height : 0;
		imagecopyresampled( $this->handle, $this->watermark, $positionX, $positionY, 0, 0, $width, $height, $width, $height );
	}

	/**
	 * Метод для получения ширины изображения водного знака
	 * @return  integer
	 * @since version 1.0
	 * @throws  LogicException
	 */
	public function getWidthWatermark()
	{
		if ( !$this->isLoaded() ) {
			throw new LogicException( 'No valid image was loaded.' );
		}
		return imagesx( $this->watermark );
	}

	/**
	 * Метод для получения высоты изображения водного знака
	 * @return  integer
	 * @since version 1.0
	 * @throws  LogicException
	 */
	public function getHeightWatermark()
	{
		if ( !$this->isLoaded() ) {
			throw new LogicException( 'No valid image was loaded.' );
		}
		return imagesy( $this->watermark );
	}
}

Интерес для нас в данном случае представляет метод applyWatermark($vertical = 0, $horizontal = 0);

В нем две переменные для определения позиционирования водного знака:

$vertical - если значение переменно равно 0, то водный знак наложится внизу изображения, если переменная равна 1, то наложение будет сверху основного изображения

$horizontal - если значение переменно равно 0, то водный знак наложится слева изображения, если переменная равна 1, то наложение будет справа основного изображения

Пример использования класса:

//загружаем изображение
$image = new Watermark( JPATH_ROOT .'/image/image.jpg' );
//загружаем изображение с водным знаком
$image->loadWatermarkFile( JPATH_ROOT . '/templates/blog/images/logo.png' );
//выполняем наложение водного знака, водный знак будет снизу справа
$image->applyWatermark( 0, 0 );
//сохраняем файл после наложения на него водного знака
$image->toFile( JPATH_ROOT .'/image/image.jpg' );

Результат работы этого скрипта:

Пример наложения водного знака

Так же бывают случаи когда нам нужно наложить на все изображения в определенной папке водный знак! Для этого мы можем воспользоваться классом JFolder и написать небольшой скрипт

//подключаем класс для работы с папками
jimport( 'joomla.filesystem.folder' );
//получаем все файлы с расширением jpg и png из папки images и всех её под папок
$files = JFolder::files( JPATH_ROOT. '/images', '\.jpg|\.png$', true, true );
foreach ($files as $file){
	$image = new Watermark( $file );
	$image->loadWatermarkFile( JPATH_ROOT . '/templates/blog/images/logo.png' );
	$image->applyWatermark( 0, 0 );
	$image->toFile( $file);
}

После выполнения такого скрипта на все найденные изображения, с расширением JPG или PNG, в папке images будет наложен водный знак!

Скачать файл с классом Waternark