Создание сайтов на 1С-Битрикс

Bitrix конвертация в webp

Класс для конвертации в webp. Выдаёт html-код тега picture.

Bitrix конвертация в webp Класс для конвертации в webp. Выдаёт html-код тега picture.

Код нужно добавить в init.php

class App
{
  static function webp($source, $quality = 100, $removeOld = false) {
        $source = $_SERVER['DOCUMENT_ROOT'].$source;
        $dir = pathinfo($source, PATHINFO_DIRNAME);
        $name = pathinfo($source, PATHINFO_FILENAME);
        $destination = $dir . DIRECTORY_SEPARATOR . $name . '.webp';
        if(!file_exists($destination)) {
            $info = getimagesize($source);
            $isAlpha = false;
            if ($info['mime'] == 'image/jpeg')
                $image = imagecreatefromjpeg($source);
            elseif ($isAlpha = $info['mime'] == 'image/gif') {
                $image = imagecreatefromgif($source);
            } elseif ($isAlpha = $info['mime'] == 'image/png') {
                $image = imagecreatefrompng($source);
            } else {
                return str_replace($_SERVER['DOCUMENT_ROOT'], '', $source);
            }
            if ($isAlpha) {
                imagepalettetotruecolor($image);
                imagealphablending($image, true);
                imagesavealpha($image, true);
            }
            imagewebp($image, $destination, $quality);

            if ($removeOld)
                unlink($source);
        }
        return str_replace($_SERVER['DOCUMENT_ROOT'], '', $destination);
    }

    static function getImage($id, $size = 'medium', $class = false, $exact = false, $retina = true, $mobileSizes = false) {
        if(!$id) {
            return false;
        }
        if (is_array($size)) {
            $sizes = $size;
        } else {
                switch ($size) {
                case 'x-small':
                    $sizes = ['width' => 60, 'height' => 60];
                    break;

                case 'small':
                    $sizes = ['width' => 500, 'height' => 500];
                    break;

                case 'big':
                    $sizes = ['width' => 840, 'height' => 550];
                    break;
                
                default:
                    $sizes = ['width' => 400, 'height' => 250];
                    break;
            }
        }
        if ($exact === false) {
            $type = BX_RESIZE_IMAGE_PROPORTIONAL;
        } elseif ($exact === true) {
            $type = BX_RESIZE_IMAGE_EXACT;
        } else {
            $type = $exact;
        }
        
        $img = CFile::ResizeImageGet($id, $sizes, $type, true);
        $webp = self::webp($img['src']);

        $result = ['img' => $img['src'], 'webp' => $webp, 'size' => ['width' => $img['width'], 'height' => $img['height']]];

        if(is_array($mobileSizes)) {
            $imgMob = CFile::ResizeImageGet($id, $mobileSizes, $type, true);
            $webpMob = self::webp($imgMob['src']);
            $resultMob = ['img_mob' => $imgMob['src'], 'webp_mob' => $webpMob, 'size_mob' => ['width' => $imgMob['width'], 'height' => $imgMob['height']]];
            $result = array_merge($result, $resultMob);
        }

        if($retina) {
            foreach ($sizes as $key => $size) {
                $sizes2x[$key] = $size * 2;
            }
            $img2x = CFile::ResizeImageGet($id, $sizes2x, $type, true);
            $webp2x = self::webp($img2x['src']);

            if(
                $exact && ($img2x['width'] == $sizes['width'] * 2 && $img2x['height'] == $sizes['height'] * 2)
            ||  !$exact && ($img2x['width'] == $sizes['width'] * 2)
            ||  !$exact && ($img2x['height'] == $sizes['height'] * 2)
              ) {
                $result2x = ['img2x' => $img2x['src'], 'webp2x' => $webp2x, 'size2x' => ['width' => $img2x['width'], 'height' => $img2x['height']]];
                $result = array_merge($result, $result2x);
            }
        }

        if($retina && is_array($mobileSizes)) {
            foreach ($mobileSizes as $key => $size) {
                $sizes2x[$key] = $size * 2;
            }
            $img2x = CFile::ResizeImageGet($id, $sizes2x, $type, true);
            $webp2x = self::webp($img2x['src']);

            if(
                $exact && ($img2x['width'] == $mobileSizes['width'] * 2 && $img2x['height'] == $mobileSizes['height'] * 2)
            ||  !$exact && ($img2x['width'] == $mobileSizes['width'] * 2)
            ||  !$exact && ($img2x['height'] == $mobileSizes['height'] * 2)
              ) {
                $result2xMob = ['img2x_mob' => $img2x['src'], 'webp2x_mob' => $webp2x, 'size2x_mob' => ['width' => $img2x['width'], 'height' => $img2x['height']]];
                $result = array_merge($result, $result2xMob);
            }
        }

        if(is_array($id) && $id['CONTENT_TYPE']) {
            $contentTypeOrig = $id['CONTENT_TYPE'];
        } else {
            $rsFile = CFile::GetByID($id);
            $arFile = $rsFile->Fetch();
            if($arFile['CONTENT_TYPE'])
                $contentTypeOrig = $arFile['CONTENT_TYPE'];
        }

        if((!isset($id['ALT']) || empty($id['ALT']) ) && $arFile['ALT']) {
            $id['ALT'] = $arFile['ALT'];
        }

        if(!is_array($id)) {
            $id = array();
            $id['ALT'] = "";
        }

        $htmlPicture = '<picture>';

        if($result['webp_mob']) {
            $htmlPicture .= '<source srcset="'.$result['webp_mob'];
                if($result['webp2x_mob'])
                    $htmlPicture .= ' 1x, '.$result['webp2x_mob'].' 2x';
            $htmlPicture .= '" media="(max-width: 520px)';
            $htmlPicture .= '" type="image/webp">';
        }

        if($result['img_mob']) {
            $htmlPicture .= '<source srcset="'.$result['img_mob'];
                if($result['img2x_mob'])
                    $htmlPicture .= ' 1x, '.$result['img2x_mob'].' 2x';
            $htmlPicture .= '" media="(max-width: 520px)';
            $htmlPicture .= '" type="'.$contentTypeOrig.'">';
        }

        $htmlPicture .= '<source srcset="'.$result['webp'];
            if($result['webp2x'])
                $htmlPicture .= ' 1x, '.$result['webp2x'].' 2x';
        $htmlPicture .= '" type="image/webp">';

        $htmlPicture .= '<source srcset="'.$result['img'];
            if($result['img2x'])
                $htmlPicture .= ' 1x, '.$result['img2x'].' 2x';
        $htmlPicture .= '" type="'.$contentTypeOrig.'">';

        $htmlPicture .= '<img src="'.$result['img'].'"';
            if($class) $htmlPicture .= ' class="'.$class.'"';
        $htmlPicture .= ' width="'.(($result['size']['width'])? $result['size']['width'] : $sizes['width']).'"';
        $htmlPicture .= ' height="'.(($result['size']['height'])? $result['size']['height'] : $sizes['height']).'"';
        $htmlPicture .= ' alt="'.$id['ALT'].'"';
        $htmlPicture .= '>';

        $htmlPicture .= '</picture>';

        return $htmlPicture;
    }

}

Вызов в коде:

$picture = ($arItem['PREVIEW_PICTURE'])? $arItem['PREVIEW_PICTURE'] : $arItem['DETAIL_PICTURE']; // Или массив или ID изображения
$sizes = ['width' => 212, 'height' => 212]; // Размеры. По-умолчанию: "medium".
// Также возможные размеры: x-small, small, big.
// Желательно для сайта настроить эти размеры (в коде) и использовать только их (по возможности) — для
// уменьшения общего объема файлов.

// Необязательные параметры:
$class = false; // Добавляет класс к тегу img. По-умолчанию false.
$exact = false; // Точные размеры (BX_RESIZE_IMAGE_EXACT). По-умолчанию false.
$retina = true; // Добавлять 2x изображения для retina-дисплеев. По-умолчанию true.
$mobileSizes = ['width' => 133, 'height' => 133]; // Размеры для телефонов (экранов меньше 520 px). По-умолчанию false.

$imageHTML = App::getImage($picture, $sizes, $class, $exact, $retina, $mobileSizes);
echo $imageHTML;

Логотип SiteBERG
Изменено: 13.08.2024 01:35

Статьи

Что нужно сделать?