При работе с инфоблоками 1С-Битрикс часто требуется вывести не оригинальное изображение, а его уменьшенную копию: например, превью новости, карточки товара, элемента каталога или галереи.
CFile::ResizeImageGet(). BX_RESIZE_IMAGE_EXACT обрезает изображение до точного размера, а BX_RESIZE_IMAGE_PROPORTIONAL уменьшает его с сохранением пропорций.
Простой пример CFile::ResizeImageGet
Допустим, в свойстве инфоблока ATT_IMG хранится изображение. В VALUE находится ID файла:
<?php
$imageId = $arResult['PROPERTIES']['ATT_IMG']['VALUE'];
?>
Получим из него превью размером 300×200:
<?php
$image = CFile::ResizeImageGet(
$imageId,
[
'width' => 300,
'height' => 200,
],
BX_RESIZE_IMAGE_EXACT,
true
);
?>
После выполнения метода в переменной $image будет массив с данными готового изображения.
Array
(
[src] => /upload/resize_cache/...
[width] => 300
[height] => 200
)
Путь к уменьшенной картинке находится в $image['src'], а фактические размеры — в $image['width']
и $image['height'].
Вывести изображение можно так:
<?php if ($image): ?>
<img
src="<?= $image['src'] ?>"
width="<?= $image['width'] ?>"
height="<?= $image['height'] ?>"
alt="<?= htmlspecialcharsbx($arResult['NAME']) ?>"
loading="lazy"
>
<?php endif; ?>
Параметры CFile::ResizeImageGet
В наиболее распространённом варианте метод вызывается так:
<?php
CFile::ResizeImageGet(
$fileId,
$size,
$resizeType,
$getSize
);
?>
$fileId
ID исходного файла в Битриксе.
$imageId = $arResult['PROPERTIES']['ATT_IMG']['VALUE'];
$size
Размер изображения задаётся массивом:
[
'width' => 300,
'height' => 200,
]
$resizeType
Определяет способ изменения размера изображения.
| Режим | Что делает |
|---|---|
BX_RESIZE_IMAGE_EXACT
|
Создаёт изображение точного размера и при необходимости обрезает лишние края |
BX_RESIZE_IMAGE_PROPORTIONAL
|
Уменьшает изображение с сохранением пропорций без обрезки |
BX_RESIZE_IMAGE_PROPORTIONAL_ALT
|
Альтернативный пропорциональный режим изменения размера |
$getSize
Если четвёртым параметром передать true, в результате будут доступны фактические ширина и высота созданного изображения:
$image['width'];
$image['height'];
Обрезка изображения до точного размера
Если нужно получить изображение строго заданного размера, например 300×200, используется BX_RESIZE_IMAGE_EXACT.
<?php
$image = CFile::ResizeImageGet(
$imageId,
[
'width' => 300,
'height' => 200,
],
BX_RESIZE_IMAGE_EXACT,
true
);
?>
Битрикс уменьшит изображение и при необходимости обрежет его края, чтобы итоговая картинка получилась точно 300×200.
Такой режим удобно использовать для:
- превью статей и новостей;
- карточек товаров;
- элементов каталога;
- фотографий сотрудников;
- галерей с одинаковыми миниатюрами.
BX_RESIZE_IMAGE_EXACT.
Уменьшение изображения без обрезки
Если изображение нужно показать полностью и обрезать его нельзя, используется BX_RESIZE_IMAGE_PROPORTIONAL.
<?php
$image = CFile::ResizeImageGet(
$imageId,
[
'width' => 600,
'height' => 400,
],
BX_RESIZE_IMAGE_PROPORTIONAL,
true
);
?>
При таком режиме исходные пропорции сохраняются, а заданные width и height определяют максимальную область, в которую должно поместиться изображение.
Например, квадратное изображение 1200×1200 при ограничении 600×400 получится размером примерно 400×400.
BX_RESIZE_IMAGE_EXACT или BX_RESIZE_IMAGE_PROPORTIONAL
| Задача | Режим |
|---|---|
| Получить строго одинаковые превью |
BX_RESIZE_IMAGE_EXACT
|
| Сохранить изображение целиком |
BX_RESIZE_IMAGE_PROPORTIONAL
|
| Карточки товаров или новости |
BX_RESIZE_IMAGE_EXACT
|
| Логотипы, схемы, документы |
BX_RESIZE_IMAGE_PROPORTIONAL
|
Полный пример для свойства инфоблока
Готовый пример для использования в шаблоне компонента:
<?php
$imageId = $arResult['PROPERTIES']['ATT_IMG']['VALUE'] ?? null;
$image = null;
if ($imageId) {
$image = CFile::ResizeImageGet(
$imageId,
[
'width' => 600,
'height' => 400,
],
BX_RESIZE_IMAGE_EXACT,
true
);
}
?>
<?php if ($image): ?>
<img
src="<?= $image['src'] ?>"
width="<?= $image['width'] ?>"
height="<?= $image['height'] ?>"
alt="<?= htmlspecialcharsbx($arResult['NAME']) ?>"
loading="lazy"
>
<?php endif; ?>
Проверка $imageId нужна, чтобы не вызывать CFile::ResizeImageGet(), если свойство изображения не заполнено.
Как уменьшить изображения из множественного свойства
Если свойство ATT_IMG множественное, в VALUE будет находиться массив ID файлов.
Например, создадим для каждого изображения превью размером 300×200:
<?php
$images = $arResult['PROPERTIES']['ATT_IMG']['VALUE'] ?? [];
foreach ($images as $imageId) {
$image = CFile::ResizeImageGet(
$imageId,
[
'width' => 300,
'height' => 200,
],
BX_RESIZE_IMAGE_EXACT,
true
);
if (!$image) {
continue;
}
?>
<div class="gallery__item">
<img
src="<?= $image['src'] ?>"
width="<?= $image['width'] ?>"
height="<?= $image['height'] ?>"
alt="<?= htmlspecialcharsbx($arResult['NAME']) ?>"
loading="lazy"
>
</div>
<?php
}
?>
Теперь все превью будут иметь одинаковый размер независимо от размеров и пропорций оригинальных фотографий.
Превью с открытием оригинала через Fancybox
Для галереи удобно выводить маленькое превью, а при клике открывать оригинальную фотографию.
Путь к оригинальному файлу можно получить через CFile::GetPath().
<?php
$images = $arResult['PROPERTIES']['ATT_IMG']['VALUE'] ?? [];
foreach ($images as $imageId) {
$preview = CFile::ResizeImageGet(
$imageId,
[
'width' => 300,
'height' => 200,
],
BX_RESIZE_IMAGE_EXACT,
true
);
$original = CFile::GetPath($imageId);
if (!$preview || !$original) {
continue;
}
?>
<a
href="<?= $original ?>"
data-fancybox="gallery"
>
<img
src="<?= $preview['src'] ?>"
width="<?= $preview['width'] ?>"
height="<?= $preview['height'] ?>"
alt="<?= htmlspecialcharsbx($arResult['NAME']) ?>"
loading="lazy"
>
</a>
<?php
}
?>
В результате на странице загружаются небольшие превью, а оригинальный файл открывается только после нажатия.
Обработка изображений в result_modifier.php
Если в шаблоне становится много логики, обработку изображений лучше перенести в result_modifier.php.
Например, заранее подготовим массив галереи:
<?php
$arResult['GALLERY'] = [];
$images = $arResult['PROPERTIES']['ATT_IMG']['VALUE'] ?? [];
foreach ($images as $imageId) {
$preview = CFile::ResizeImageGet(
$imageId,
[
'width' => 300,
'height' => 200,
],
BX_RESIZE_IMAGE_EXACT,
true
);
if (!$preview) {
continue;
}
$arResult['GALLERY'][] = [
'ORIGINAL' => CFile::GetPath($imageId),
'PREVIEW' => $preview['src'],
'WIDTH' => $preview['width'],
'HEIGHT' => $preview['height'],
];
}
После этого в template.php останется только вывод HTML:
<?php foreach ($arResult['GALLERY'] as $image): ?>
<a
href="<?= $image['ORIGINAL'] ?>"
data-fancybox="gallery"
>
<img
src="<?= $image['PREVIEW'] ?>"
width="<?= $image['WIDTH'] ?>"
height="<?= $image['HEIGHT'] ?>"
alt="<?= htmlspecialcharsbx($arResult['NAME']) ?>"
loading="lazy"
>
</a>
<?php endforeach; ?>
result_modifier.php, а template.php оставить только для вывода.
Где хранятся уменьшенные изображения
Созданные через CFile::ResizeImageGet() изображения Битрикс сохраняет в каталоге /upload/resize_cache/.
При следующем запросе изображения с такими же параметрами используется уже созданная копия.
Поэтому самостоятельно создавать отдельные каталоги для превью в большинстве случаев не требуется.
/upload/resize_cache/
без необходимости. После очистки Битрикс будет создавать нужные превью заново.
Короткий рабочий пример
Если нужно просто получить превью размером 300×200
с обрезкой лишней части изображения:
<?php
$image = CFile::ResizeImageGet(
$imageId,
[
'width' => 300,
'height' => 200,
],
BX_RESIZE_IMAGE_EXACT,
true
);
?>
Путь к готовой картинке:
$image['src'];
Фактические размеры:
$image['width'];
$image['height'];
Путь к оригинальному файлу:
CFile::GetPath($imageId);
Итог
Для уменьшения и обрезки изображений в 1С-Битрикс в большинстве случаев достаточно стандартного метода CFile::ResizeImageGet().
-
BX_RESIZE_IMAGE_EXACT— когда нужен точный размер с обрезкой. -
BX_RESIZE_IMAGE_PROPORTIONAL— когда изображение нужно уменьшить целиком без обрезки. -
CFile::GetPath()— когда требуется получить путь к оригинальному файлу.
Для небольших шаблонов обработку можно выполнять непосредственно в template.php. Если логики становится много, удобнее заранее подготовить данные в result_modifier.php.
Комментарии