Answer the question
In order to leave comments, you need to log in
How to properly adapt this code to work with @2x?
Hello!
I have a module that automatically converts images to WebP
<?php
function udisabled($imagepath)
{
// Список запрещенных путей для преобразования
$disabled_path = array(
'dleimages', 'engine',
);
// Проверяем список запрещенных путей для преобразования
foreach($disabled_path as $disabled)
{
if(strpos($imagepath, $disabled) !== FALSE) return false;
}
return true;
}
function uimages($html)
{
global $config, $uconfig, $home_page;
$htmlParser = new HtmlDocument();
$page = $htmlParser->load($html);
// Список форматов изображений разрешенных к преобразованию
$allowed_extensions = array();
if($uconfig['convert_png']) $allowed_extensions[] = 'png';
if($uconfig['convert_jpg'])
{
$allowed_extensions[] = 'jpg';
$allowed_extensions[] = 'jpeg';
}
if($uconfig['convert_gif']) $allowed_extensions[] = 'gif';
// Качество сжатия изображений
$quality = intval($uconfig['image_quality']);
if(empty($quality) OR $quality < 0)
{
$quality = 80;
}
foreach($page->find('[data-uwebp="true"] img') as $image)
{
// Проверяем какой стоит аттрибут src или data-src
if(isset($image->src))
{
$imagepath = $image->src;
} else if(isset($image->{'data-src'}))
{
$imagepath = $image->{'data-src'};
}
// Записываем в переменную путь к изображению, для использования в разметке
$shema_image_path = $imagepath;
// Проверяем список запрещенных путей для преобразования
if(!udisabled($imagepath)) continue;
// Проверяем, чтобы изображение находилось на сервере
$addhome = false;
if(strpos($imagepath, "http://") !== false OR strpos($imagepath, "https://") !== false)
{
if(strpos($imagepath, $home_page) === false)
{
continue;
} else {
// Убираем URL сайта из пути изображения
$imagepath = str_replace($home_page, "", $imagepath);
}
} else {
$addhome = true;
}
// Информация об изображении
$imageinfo = pathinfo($imagepath);
// Путь изображения на сервере
$image_on_server = ROOT_DIR . $imageinfo['dirname'] . '/' . $imageinfo['basename'];
$image_webp_on_server = ROOT_DIR . $imageinfo['dirname'] . '/' . $imageinfo['filename'] . '.webp';
$output_webp_image = str_replace(ROOT_DIR, "", $image_webp_on_server);
// Проверяем наличие изображения на сервере, а также разрешен ли формат к преобразованию
if(file_exists($image_on_server) === FALSE OR in_array($imageinfo['extension'], $allowed_extensions) === FALSE)
{
continue;
}
// Проверяем конвертировалось изображение ранее, если нет - конвертируем его
if(!file_exists($image_webp_on_server))
{
// Если это GIF изображение и включен режим преобразования в анимированные WebP изображения
if(mime_content_type($image_on_server) == "image/gif" AND $uconfig['convert_gif'] AND $uconfig['animate_webp'] AND is_animated_gif($image_on_server))
{
// Обязательно получаем размеры изображения для корректного преобразования в анимированный WebP
$gif_size = getimagesize($image_on_server);
try {
$gifStream = new FileStream($image_on_server);
$gifDecoder = new Decoder($gifStream);
$gifRenderer = new Renderer($gifDecoder);
$gifRenderer->start(function (FrameRenderedEvent $event) {
$GLOBALS['frames'][] = getFrameData($event->decodedFrame->createGDImage(), $event->decodedFrame->getDuration() * 10);
});
$fileWEBP = "";
$fileHeader = "";
$fileContents = "";
$fileContents .="VP8X";
$headChunkSize = bytesToString(toUint32(10));
$oVP8XflagsBin = "00010010 00000000 00000000 00000000";
$oVP8Xflags = bytesToString(binaryToBytes($oVP8XflagsBin));
$oCanvasSize = bytesToString(toUint24($gif_size[0] - 1)) . bytesToString(toUint24($gif_size[1] - 1));
$fileContents .= $headChunkSize. $oVP8Xflags. $oCanvasSize;
$fileContents .="ANIM";
$animChunkSize = bytesToString(toUint32(6));
$oLoopCount = str_repeat(chr(0), 2);
$oBackGround = str_repeat(chr(0), 4);
$fileContents .= $animChunkSize . $oBackGround . $oLoopCount;
foreach ($GLOBALS['frames'] as $frame)
{
$fileContents .= "ANMF";
$frameDataChunkSize = bytesToString(toUint32(strlen($frame['frameData']) + 16));
$fOrigin = str_repeat(chr(0), 6);
$fSize = $frame['width'] . $frame['height'];
$fDuration = $frame['duration'];
$fFlagsBin = "00000010";
$fFlags = bytesToString(binaryToBytes($fFlagsBin));
$fileContents .= $frameDataChunkSize . $fOrigin . $fSize . $fDuration . $fFlags . $frame['frameData'];
}
$fileSize = bytesToString(toUint32(strlen($fileContents) + 4));
$fileHeader = "RIFF" . $fileSize . "WEBP";
$fileWEBP = $fileHeader . $fileContents;
if(!file_put_contents($image_webp_on_server, $fileWEBP))
{
continue;
}
} catch(RuntimeException $e)
{
continue;
}
} else
{
\ImageConverter\convert($image_on_server, $image_webp_on_server, $quality);
}
}
// Если в настройках CMS включена опция: 'Отложенная загрузка изображений'
if($config['image_lazy'])
{
$data_attr = 'data-srcset';
$image->{'data-src'} = $image->src;
$image->src = null;
} else
{
$data_attr = 'srcset';
}
// Если включена разметка изображений schema.org
if($uconfig['schema_org'])
{
$schema_org_html = "";
// contentUrl или image – (URL) ссылка на изображение. Обязательное поле, если не заполнено thumbnail. Без заполнения одного из этих полей, данные не будут обработаны. Предпочтительно contentUrl, обязательно ссылка именно на файл изображения;
//$image->attr['itemprop'] = "contentUrl";
$schema_array['image'] = $shema_image_path;
// Если нужно добавить главную страницу сайта к URL изображения
if($addhome)
{
if($home_page[strlen($home_page) - 1] == "/")
{
$home_page = mb_substr($home_page, 0, -1);
}
$schema_array['image'] = $home_page . $imageinfo['dirname'] . '/' . $imageinfo['basename'];
}
// description – (Text) описание изображения;
if(!empty($image->alt)) $schema_array['description'] = $image->alt;
// Получаем размеры изображения
if($imagesize = getimagesize($image_on_server))
{
list($width, $height, $type, $attr) = $imagesize;
if($width > 0) $schema_array['width'] = $width . 'px';
if($height > 0) $schema_array['height'] = $height . 'px';
}
if(!empty($schema_array))
{
foreach($schema_array as $skey => $value)
{
$value = str_replace("&amp;", "&", htmlspecialchars(strip_tags(stripslashes($value)), ENT_QUOTES, $config['charset']));
$schema_org_html .= '<meta itemprop="' . $skey . '" content="' . $value . '">';
}
}
$webpTemplate = <<<HTML
<picture itemscope itemtype="http://schema.org/ImageObject">
<source type="image/webp" {$data_attr}="{$output_webp_image}">
{$image->outertext}
{$schema_org_html}
</picture>
HTML;
} else {
$webpTemplate = <<<HTML
<picture>
<source type="image/webp" {$data_attr}="{$output_webp_image}">
{$image->outertext}
</picture>
HTML;
}
$image->outertext = $webpTemplate;
}
return $htmlParser->save();
}
?>
<img srcset="image.png" src="image.png">
<picture itemscope="" itemtype="http://schema.org/ImageObject">
<source type="image/webp" data-srcset="/image.webp" srcset="/image.webp">
<img srcset="image.png" src="image.png">
<meta itemprop="image" content="image.png">
<meta itemprop="description" content="Title">
<meta itemprop="width" content="128px">
<meta itemprop="height" content="128px">
</picture>
<img srcset="image.png, image-retina.png 2x" src="image.png">
<source type="image/webp" data-srcset="/image.webp" srcset="/image.webp, image-retina.webp 2x">
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question