Водяной знак без изменения размера изображения

Водяной знак без изменения размера изображения

2050
04.04.2017
13.05.2017

У битрикса есть отличная функция, CFile::ResizeImageGet, позволяющая изменить размер изображения с наложением поверх него водяного знака, но если использовать данную функцию с сохранением размера, то функция просто вернет исходное изображение, без изменения размера и без наложения водяного знака.

Рассмотрим пример наложения водяного знака в виде домена сайта (или любого другого текста) на главное изображение элемента инфоблока в шаблоне компонента catalog.element.

В файле result_modifier шаблона определяем водяной знак, как массив разных знаков (для размещения знака в левом верхнем углу, правом нижнем углу и по центру):

$arWaterMark = Array(
	array(
		"name" => "watermark",
		"position" => "tl",
		"type" => "text",
		'alpha_level'    =>   '50',
		"fill" => "exact",
		"text" => "pai-bx.com",
		"color"=> "#000000",
		"font"           => $_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/fonts/PTSansRegular.ttf",
		"use_copyright"  => "Y"
	),
	array(
		"name" => "watermark",
		"position" => "br",
		"type" => "text",
		'alpha_level'    =>   '50',
		"fill" => "exact",
		"text" => "pai-bx.com",
		"color"=> "#FF0000",
		"font"           => $_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/fonts/PTSansRegular.ttf",
		"use_copyright"  => "Y"
	),
	array(
		"name" => "watermark",
		"position" => "center",
		"type" => "text",
		'alpha_level'    =>   '50',
		"fill" => "exact",
		"text" => "pai-bx.com",
		"color"=> "#FFFFFF",
		"font"           => $_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/fonts/PTSansRegular.ttf",
		"use_copyright"  => "Y"
	)
);

Дальше создаем функцию для наложения водяного знака:

function AddWaterMarkToImg($image, $arWaterMark)
{
	$documentRoot = \Bitrix\Main\Application::getDocumentRoot();
	if (
		(is_array($image) && !isset($image['ID']))
		||
		(!is_array($image) && intval($image) <= 0)
	) return false;

	if (!is_array($arWaterMark)) return false;

	$io = \CBXVirtualIo::GetInstance();
	if (!is_array($image)) $image = \CFile::GetByID(intval($image))->Fetch();

	if (!is_array($image)) return false;

	$absPath = $documentRoot . $image['SRC'];
	if (!$io->FileExists($absPath)) return false;
	$uploadDirName = \COption::GetOptionString("main", "upload_dir", "upload");
	$cacheImageFile = '/' . $uploadDirName . '/resize_cache/' . $image['SUBDIR'] . '/' . $image['WIDTH'] . '_' . $image['HEIGHT'] . '_0_'
		. md5(serialize($arWaterMark)) . '/' . $image['FILE_NAME'];
	$arSourceFileSizeTmp = \CFile::GetImageSize($absPath);
	if (!in_array($arSourceFileSizeTmp[2], array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP)))
		return false;

	if($arSourceFileSizeTmp[2] == IMAGETYPE_JPEG)
	{
		$exifData = \CFile::ExtractImageExif($io->GetPhysicalName($absPath));
		if ($exifData  && isset($exifData['Orientation']))
		{
			$orientation = $exifData['Orientation'];
			//swap width and height
			if ($orientation >= 5 && $orientation <= 8)
			{
				$tmp = $arSourceFileSizeTmp[1];
				$arSourceFileSizeTmp[1] = $arSourceFileSizeTmp[0];
				$arSourceFileSizeTmp[0] = $tmp;
			}
		}
	}
	if ($io->Copy($absPath, $documentRoot.$cacheImageFile))
	{
		switch ($arSourceFileSizeTmp[2])
		{
			case IMAGETYPE_GIF:
				$sourceImage = imagecreatefromgif($io->GetPhysicalName($absPath));
				$bHasAlpha = true;
				break;
			case IMAGETYPE_PNG:
				$sourceImage = imagecreatefrompng($io->GetPhysicalName($absPath));
				$bHasAlpha = true;
				break;
			case IMAGETYPE_BMP:
				$sourceImage = \CFile::ImageCreateFromBMP($io->GetPhysicalName($absPath));
				$bHasAlpha = false;
				break;
			default:
				$sourceImage = imagecreatefromjpeg($io->GetPhysicalName($absPath));
				if ($sourceImage === false)
				{
					ini_set('gd.jpeg_ignore_warning', 1);
					$sourceImage = imagecreatefromjpeg($io->GetPhysicalName($absPath));
				}

				if ($orientation > 1)
				{
					$properlyOriented = \CFile::ImageHandleOrientation($orientation, $sourceImage);

					$jpgQuality = intval(\COption::GetOptionString('main', 'image_resize_quality', '95'));

					if ($jpgQuality <= 0 || $jpgQuality > 100)
						$jpgQuality = 95;

					if ($properlyOriented)
					{
						imagejpeg($properlyOriented, $io->GetPhysicalName($cacheImageFile), $jpgQuality);
						$sourceImage = $properlyOriented;
					}
				}
				$bHasAlpha = false;
				break;
		}

		$arSourceSize = array("x" => 0, "y" => 0, "width" => $image["WIDTH"], "height" => $image["HEIGHT"]);

		if(\CFile::IsGD2()){
			$picture = ImageCreateTrueColor($image["WIDTH"], $image["HEIGHT"]);
			if($arSourceFileSizeTmp[2] == IMAGETYPE_PNG)
			{
				$transparentcolor = imagecolorallocatealpha($picture, 0, 0, 0, 127);
				imagefilledrectangle($picture, 0, 0, $image["WIDTH"], $image["HEIGHT"], $transparentcolor);

				imagealphablending($picture, false);
				imagecopyresampled($picture, $sourceImage,
					0, 0, $arSourceSize["x"], $arSourceSize["y"],
					$image["WIDTH"], $image["HEIGHT"], $arSourceSize["width"], $arSourceSize["height"]);
				imagealphablending($picture, true);
			}
			elseif($arSourceFileSizeTmp[2] == IMAGETYPE_GIF)
			{
				imagepalettecopy($picture, $sourceImage);

				//Save transparency for GIFs
				$transparentcolor = imagecolortransparent($sourceImage);
				if($transparentcolor >= 0 && $transparentcolor < imagecolorstotal($sourceImage))
				{
					$RGB = imagecolorsforindex($sourceImage, $transparentcolor);
					$transparentcolor = imagecolorallocate($picture, $RGB["red"], $RGB["green"], $RGB["blue"]);
					imagecolortransparent($picture, $transparentcolor);
					imagefilledrectangle($picture, 0, 0, $arSourceSize["width"], $arSourceSize["height"], $transparentcolor);
				}

				imagecopyresampled($picture, $sourceImage,
					0, 0, $arSourceSize["x"], $arSourceSize["y"],
					$arSourceSize["width"], $arSourceSize["height"], $arSourceSize["width"], $arSourceSize["height"]);
			}
			else
			{
				imagecopyresampled($picture, $sourceImage,
					0, 0, $arSourceSize["x"], $arSourceSize["y"],
					$arSourceSize["width"], $arSourceSize["height"], $arSourceSize["width"], $arSourceSize["height"]);
			}
		}
		else
		{
			$picture = imagecreate($arSourceSize["width"], $arSourceSize["height"]);
			imagecopyresized($picture, $sourceImage,
				0, 0, $arSourceSize["x"], $arSourceSize["y"],
				$arSourceSize["width"], $arSourceSize["height"], $arSourceSize["width"], $arSourceSize["height"]);
		}
		$bNeedCreatePicture = true;

		if(is_array($arWaterMark))
		{
			foreach ($arWaterMark as $watermark)
			{ // тут идет перебор всех составляющих водяного знака
				$watermark["name"] = "watermark";
				$bNeedCreatePicture |= \CFile::Watermark($picture, $watermark);
			}
		}

		if ($bNeedCreatePicture)
		{
			if($io->FileExists($documentRoot.$cacheImageFile))
				$io->Delete($documentRoot.$cacheImageFile);
			switch ($arSourceFileSizeTmp[2])
			{
				case IMAGETYPE_GIF:
					imagegif($picture, $io->GetPhysicalName($documentRoot.$cacheImageFile));
					break;
				case IMAGETYPE_PNG:
					imagealphablending($picture, false );
					imagesavealpha($picture, true);
					imagepng($picture, $io->GetPhysicalName($documentRoot.$cacheImageFile));
					break;
				default:
					if ($arSourceFileSizeTmp[2] == IMAGETYPE_BMP)
						$cacheImageFile .= ".jpg";
					if($jpgQuality === false)
						$jpgQuality = intval(\COption::GetOptionString('main', 'image_resize_quality', '95'));
					if($jpgQuality <= 0 || $jpgQuality > 100)
						$jpgQuality = 95;
					imagejpeg($picture, $io->GetPhysicalName($documentRoot.$cacheImageFile), $jpgQuality);
					break;
			}
			imagedestroy($picture);
		}
	} else {
		$errors = $io->GetErrors();
		static::pre(array($cacheImageFile,$absPath,$errors), false, true);
	}
	return $cacheImageFile;
}

И прогоним наше изображение через данную функцию:

$arResult['DETAIL_PICTURE']['WATERMARK'] = AddWaterMarkToImg($arResult['DETAIL_PICTURE'],$arWaterMark);
if(strlen($arResult['DETAIL_PICTURE']['WATERMARK'])>0)
	$arResult["DETAIL_PICTURE"]["SRC"] = $arResult['DETAIL_PICTURE']['WATERMARK'];

Все!

Вот такое решение удалось вытянуть из системной функции GetResizeFile.



Благодарю за внимание! Делитесь вашими замечаниями в комментариях ниже.


P.S. Обращайтесь ко мне за приобретением лицензий и продлений на 1C-Битрикс "Управление сайтом", лицензий на облачную и коробочную версии Битрикс 24 а также за приобретением и внедрением готовых решений на базе 1С-Битрикс от партнеров. За более подробной информацией свяжитесь со мной любым удобным для вас способом


Комментарии

Еще никто не комментировал данную публикацию. Будьте первыми!

Добавить комментарий

captcha

Возврат к списку