Конвертация картинок в webp на битриксе

11k
Алексей,
Конвертация картинок в webp на битриксе
Конвертация картинок в webp на битриксе

Картинки в формате WebP "весят" значительно меньше, а сам формат уже поддерживается многими браузерами. К тому использовать его достаточно просто.

Картинки в формате WebP "весят" значительно меньше, а сам формат уже поддерживается многими браузерами. К тому использовать его достаточно просто.

Для начала, необходимо добавить скрипт конвертации (например в init.php), который будет создавать копию картинки (png или jpeg) в формате webp. Пример такого скрипта:

function makeWebp ($src, $rewrite = false) {
	
	if ($src && function_exists('imagewebp')) {
		$newImgPath = str_ireplace(array('.jpg', '.jpeg', '.gif', '.png'), '.webp', $src);
		if (!file_exists($_SERVER['DOCUMENT_ROOT'].$newImgPath) || $rewrite) {
			$info = getimagesize($_SERVER['DOCUMENT_ROOT'].$src);
			if ($info !== false && ($type = $info[2])) {
				switch ($type) {
					case IMAGETYPE_JPEG:
						$newImg = imagecreatefromjpeg($_SERVER['DOCUMENT_ROOT'].$src);
						break;
					case IMAGETYPE_GIF:
						$newImg = imagecreatefromgif($_SERVER['DOCUMENT_ROOT'].$src);
						break;
					case IMAGETYPE_PNG:
						$newImg = imagecreatefrompng($_SERVER['DOCUMENT_ROOT'].$src);
						imagepalettetotruecolor($newImg);
						imagealphablending($newImg, true);
						imagesavealpha($newImg, true);
						break;
				}
				if ($newImg) {
					imagewebp($newImg, $_SERVER['DOCUMENT_ROOT'].$newImgPath, 90);
					imagedestroy($newImg);
				}
			}
		}

		if (file_exists($_SERVER['DOCUMENT_ROOT'].$newImgPath)) { // Файл мог не создаться по каким-либо причинам
			return $newImgPath;
		}
	}
	
	return false;
}

Далее все просто, передаете в функцию относительный путь картинки в формате jpg или png, в ответе получаете путь до картинки в формате webp.

В реалиях битрикс это может выглядеть так (resul_modifier.php компонента списка новостей)

foreach ($arResult["ITEMS"] as $i => $arItem) {
	// resize image
	if ($arItem['PREVIEW_PICTURE']['SRC']) {
		$file = CFile::ResizeImageGet($arItem['PREVIEW_PICTURE'], array('width' => 605, 'height' => (605*0.6)), BX_RESIZE_IMAGE_PROPORTIONAL, true);
		$arResult["ITEMS"][$i]['PREVIEW_PICTURE']['SRC'] = $file['src'];
		$arResult["ITEMS"][$i]['PREVIEW_PICTURE']['SRC_WEBP'] = makeWebp($file['src']);
	}
}

Далее в шаблоне само изображение нужно вывести через тег picture, где один из источников будет картинка в формате webp

<picture>
	<?if ($arItem["PREVIEW_PICTURE"]["SRC_WEBP"]) :?>
		<source type="image/webp" srcset="<?=$arItem["PREVIEW_PICTURE"]["SRC_WEBP"]?>">
	<?endif;?>
	<img src="<?=$arItem["PREVIEW_PICTURE"]["SRC"]?>" alt="<?=$arItem["PREVIEW_PICTURE"]["ALT"]?>" />
</picture>

Единственный минус, теперь на хостинге будут храниться две картинки вместо одной.

Существует и более простое решение, которое не требует навыков программирования.
Готовый модуль OptiPic CDN – простое решение проблемы "Используйте современные форматы изображений" согласно рекомендациям Google Pagespeed Insights.
Он автоматически конвертирует изображения в современный формат Webp (для браузеров, которые поддерживают webp). А для браузеров, которые не поддерживают webp, OptiPic оптимизирует (сжимает) старые форматы png и jpeg.

Есть вопросы или нашли ошибку? Напишите комментарий (можно без регистрации), отвечать стараюсь быстро.

Опубликовано 29 августа 2019 | Обновлено 2 августа 2023
готовый код, производительность, разработчику, костыли
Поделиться
Похожие статьи
Как получить ограничения доставки по платежным системам
Понадобилось вне компонента оформления заказа показать какие способы оплаты доступны для той или ино...
Читать дальше » 0
Алексей,
Как убрать js и css файлы ядра
Часть можно убрать отключив галочки в настройках модуля, часть только вырезав при завершении буфериз...
Читать дальше » 0
Алексей,
Комментарии
❮…❯
Авторизуйтесь чтобы получать уведомления об ответе
18 апр 2023
Спасибо друг! Хороший скрипт!
22 апр 2022
Картинка то создается webp, только в размерах никакой разницы нет
Алексей
22 апр 2022
Павел, в размерах занимаемого места на диске? Должна быть разница, значительная. А вот размеры по ширине/высоте и не должны меняться.
9 сен 2021
День добрый! Не могу понять, почему не работает. Подскажите, пожалуйста: Файл temlate.php по ссылке в облаке yadi.sk/d/FtONR2biuQ4tGA
Алексей
9 сен 2021
Алексей, добрый. temlate.php не полный по ссылке? Потому что он в таком виде точно работать не будет. Не хватает еще одного цикла для вывода изображений. Ошибки пишет какие-нибудь? Проверьте наличие функции. var_dump(function_exists('imagewebp')); что возвращает?
9 сен 2021
Алексей, ничего не возвращает. Сайт не загружается. Обновил temlate.php - посмотрите, в коде вообще не силен(( а сайт оч сильно провисает в pagespeed
9 сен 2021
Алексей, yadi.sk/d/YdjQoF_BoLKUTw - это стандартный шаблон компонента, который я пытаюсь изменить
Алексей
9 сен 2021
Алексей, напишите мне на эл. почту budagovalexey@gmail.com, расскажу, какой код куда вставить.
9 сен 2021
Алексей, благодарю за помощь в настройке! Скрипт работает на ура
16 июн 2021
А альфа канал (прозрачность в png) поддерживается?
Алексей
16 июн 2021
Виктор, должен. Но с ним бывают проблемы, когда слой заполняется черным цветом. Где-то я с этим встречался и успешно решал, но уже не вспомню. В интернете есть описание решения.
7 июл 2021
Алексей, сделал так. Вроде работает. case IMAGETYPE_PNG: $newImg = imagecreatefrompng($_SERVER['DOCUMENT_ROOT'].$src); imagepalettetotruecolor($newImg); imageAlphaBlending($newImg, true); imageSaveAlpha($newImg, true); break; И ещё у вас на сайте почти не реально оставить комментарий. Не возможно нажать на гугло капчу. Её перекрывает блок с классом ab-comments__form-submit-cont.
Алексей
8 июл 2021
Виктор, спасибо за пример и за фидбэк по форме, поправил вёрстку.
23 окт 2020
Чел, а ты уверен, что хорошо понимаешь понятие "конвертация в вебп"? Потому что всё что я вижу в твоём скрипте, это банальное переименование с ресайзом.
Алексей
23 окт 2020
Ы, чтение чужого кода не твой конек. Обрати внимание на imagewebp, эта функция создаёт webp изображение. Ресайза в функции нет, картинка создаётся с теми же размерами.
25 окт 2020
Алексей, ну хорошо. Допустим, на основание чего, он должен конвертировать его в вебп? В штатном битриксе, этого просто нету.
25 окт 2020
Ы, а всё отбой. Действительно используется пхп класс. А то я подумал это пустой штатный.
20 авг 2020
Это не единственный минус. Ваша реализация при каждом обращении к функции makeWebp() выясняет формат исходной картинки, выполняет её загрузку в память и только после этого проверяет, а нужно ли вообще всё это было делать. Лучше всего не морочиться с выяснением точного формата, а просто заменить расширение файла на webp, проверить его наличие и уже дальше что-то делать только если webp-файла нет.
Алексей
20 авг 2020
А., можно немного поменять функцию, проверять наличие созданной картинки webp, в самом начале, до imagecreacefrom*, тогда в память исходная картинка грузится не будет. Обновлю код в ближайшее время, спасибо.
Алексей
7 сен 2020
А., обновил, теперь проверяется только file_exists
Картинки в формате WebP "весят" значительно меньше, а сам формат уже поддерживается многими браузерами. К тому использовать его достаточно просто.