Автоматический ресайз картинок при добавлении (Битрикс)

03.12.2014

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


Для начала, давайте разберемся, зачем вообще обрезать изображения.

  • Во-первых — контроль. Не редко бывает, что картинки загружают сами пользователи, либо же контент-менеджеры, которые не задумываются сколько весят файлы, а кидают всё подряд. Когда за все отвечает сама система — получается намного спокойней.
  • Во-вторых — это скорость. Зачем грузить изображение весом в несколько мегабайт, если оно должно быть 300х300 пикселей? Пожалейте пользователь со слабым интернетом!
  • В третьих — это экономия места на жестком диске, а оно как всем известно — не резиновое. Так зачем заполнять его огромными картинками

Реализация

Как правило в битриксе для прикрепления большого кол-ва картинок используют множественное свойство элемента инфоблока типа «Файл» с указанием набора расширений графических файлов.

Штатно 1С-Битрикс позволяет задать размеры для детального изображения и изображения анонсов, но в случае свойства типа «Файл» таких настроек, к сожалению нет.

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

Подробнее, про механизм событий, вы можете узнать из учебного курса

Итак. Для начала зайдем на наш сайт по адресу: /bitrix/php_interface/. В этой директории должен располагаться файл init.php. Если его нет — необходимо его создать.

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

<?
// События которые срабатывают при создании или изменении элемента инфоблока
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "ResizeUploadedPhoto");
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "ResizeUploadedPhoto");

function ResizeUploadedPhoto(&$arFields) {
  global $APPLICATION;
  CModule::IncludeModule('iblock');
  $IBLOCK_ID = 6; // ID инфоблока свойство которых нуждается в масштабировании
  $PROPERTY_CODE = "PHOTOS";  // код свойства
  $imageMaxWidth = 1000; // Максимальная ширина картинки
  $imageMaxHeight = 850; // Максимальная высота картинки
  // для начала убедимся, что изменяется элемент нужного нам инфоблока
  if($arFields["IBLOCK_ID"] == $IBLOCK_ID) {
	$VALUES = $VALUES_OLD = array();
	//Получаем свойство значение сво-ва $PROPERTY_CODE
	$res = CIBlockElement::GetProperty($arFields["IBLOCK_ID"], $arFields["ID"], "sort", "asc", array("CODE" => $PROPERTY_CODE));
	while ($ob = $res->GetNext()) {
		$file_path = CFile::GetPath($ob['VALUE']); // Получаем путь к файлу
		if($file_path) {
			$imsize = getimagesize($_SERVER["DOCUMENT_ROOT"].$file_path); //Узнаём размер файла
			// Если размер больше установленного максимума
			if($imsize[0] > $imageMaxWidth or $imsize[1] > $imageMaxHeight) {
				// Уменьшаем размер картинки
				$file = CFile::ResizeImageGet($ob['VALUE'], array(
						'width'=>$imageMaxWidth,
						'height'=>$imageMaxHeight
					), BX_RESIZE_IMAGE_PROPORTIONAL, true);
				// добавляем в массив VALUES новую уменьшенную картинку
				$VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file["src"]);
			} else {
				// добавляем в массив VALUES старую картинку
				$VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file_path);
			}
			// Собираем в массив ID старых файлов для их удаления (чтобы не занимали место)
			$VALUES_OLD[] = $ob['VALUE']; 
		}
	}
	// Если в массиве есть информация о новых файлах
	if(count($VALUES) > 0) {
		$PROPERTY_VALUE = $VALUES;  // значение свойства
		// Установим новое значение для данного свойства данного элемента
		CIBlockElement::SetPropertyValuesEx($arFields["ID"], $arFields["IBLOCK_ID"], array($PROPERTY_CODE => $PROPERTY_VALUE));
		// Удаляем старые большие изображения
		foreach ($VALUES_OLD as $key=>$val) {
			CFile::Delete($val);
		}
	}
	unset($VALUES);
	unset($VALUES_OLD);
  }
}
?>

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

Материалы и использованные в статье функции:

Метки: , ,