Есть в битриксе всеми любимая функция - CFile::ResizeImageGet.
Но что делать, если необходимо изменить размер фото, не обрезая видимую честь, а добавляя к ней поля?
К сожалению такого способа кадрирования в ResizeImageGet и битриксе вообще нет (или я ошибаюсь?)
Поэтому будем писать костыль.
Задача; Кадрировать фото под заданный размер, с сохранением пропорции, добавляя необходимые поля.
Решение: Использовать ResizeImageGet два раза
Код;
Комментарии:
Основная магия в хардкоде 5145 второго вызова CFile::ResizeImageGet. Это файл с прозрачным (или любым другим) фоном, для создания полей. Он должен быть больше, чем конечное изображение, иначе второй вызов CFile::ResizeImageGet( не отработает. Файл был залит в медиабиблиотеку, после чего его ID был получен из таблицы b_files. Обращаю внимание, что тут нельзя использовать прямую ссылку на картинку.
Данный код можно поместить к result-modifier.php для обрезания на лету или в обработчик события для для сохранения его вместо изначального.
Заключение:
Если кто-то предложит более правильный способ решения этой задачи, прошу опубликовать его в комментах, т.к. заказчик часто просит именно такой вариант кадрирования, с добавлением прозрачных полей.
Но что делать, если необходимо изменить размер фото, не обрезая видимую честь, а добавляя к ней поля?
К сожалению такого способа кадрирования в ResizeImageGet и битриксе вообще нет (или я ошибаюсь?)
Поэтому будем писать костыль.
Задача; Кадрировать фото под заданный размер, с сохранением пропорции, добавляя необходимые поля.
Решение: Использовать ResizeImageGet два раза
Код;
<? // проверим, есть ли картинка, которую будем кадрировать if ($arResult['ITEM']['PREVIEW_PICTURE']['ID']>0){ // Зададим размер выходной картинки $width = 300; $height = 300; // Кадрируем картинку, с сохранением пропорции. $image = CFile::ResizeImageGet( $arResult['ITEM']['PREVIEW_PICTURE']['ID'], array("width" => $width, "height" => $height), BX_RESIZE_IMAGE_PROPORTIONAL, true, false, false, 100 // качество сжатия выходного файла должно быть 100, чтобы избежать лишних потерь качества. ); // Проверяем, прошло ли кадрирование. Если нет, то берем изначальное изображение. if (strlen($image['src'])<3){$image['src']=$arResult['ITEM']['PREVIEW_PICTURE']['SRC'];} // А теперь накладываем на прозрачный фон нужного размера, изначальную картинку, используя фильтр watermark $arWaterMark = Array( array( "name" => "watermark", "position" => "center", "type" => "image", "size" => "real", "file" => $_SERVER['DOCUMENT_ROOT'].$image['src'], // Путь к картинке полученной в первом вызове CFile::ResizeImageGet "fill" => "exact", ) ); $file = CFile::ResizeImageGet( 5145, // id файоа с прозрачным фоном в b_files array("width" => $width, "height" => $height), BX_RESIZE_IMAGE_EXACT, true, $arWaterMark, false, 100 // Тут можем менять качество конечной картинки, для оптимизации размера страницы ); // Заменяем начальную картинку, на полученную. $arResult['ITEM']['PREVIEW_PICTURE']['SRC'] = $file['src']; $arResult['ITEM']['PREVIEW_PICTURE']['WIDTH'] = $file['width']; $arResult['ITEM']['PREVIEW_PICTURE']['HEIGHT'] = $file['height']; } ?> |
Комментарии:
Основная магия в хардкоде 5145 второго вызова CFile::ResizeImageGet. Это файл с прозрачным (или любым другим) фоном, для создания полей. Он должен быть больше, чем конечное изображение, иначе второй вызов CFile::ResizeImageGet( не отработает. Файл был залит в медиабиблиотеку, после чего его ID был получен из таблицы b_files. Обращаю внимание, что тут нельзя использовать прямую ссылку на картинку.
Данный код можно поместить к result-modifier.php для обрезания на лету или в обработчик события для для сохранения его вместо изначального.
Заключение:
Если кто-то предложит более правильный способ решения этой задачи, прошу опубликовать его в комментах, т.к. заказчик часто просит именно такой вариант кадрирования, с добавлением прозрачных полей.