View source
<?php
namespace Drupal\webp;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileSystem;
use Drupal\Core\Image\ImageFactory;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Imagick;
class Webp {
use StringTranslationTrait;
protected $imageFactory;
protected $logger;
protected $defaultQuality;
protected $fileSystem;
public function __construct(ImageFactory $imageFactory, LoggerChannelFactoryInterface $loggerFactory, TranslationInterface $stringTranslation, ConfigFactoryInterface $configFactory, FileSystem $fileSystem) {
$this->imageFactory = $imageFactory;
$this->logger = $loggerFactory
->get('webp');
$this
->setStringTranslation($stringTranslation);
$this->defaultQuality = $configFactory
->get('webp.settings')
->get('quality');
$this->fileSystem = $fileSystem;
}
public function createWebpCopy($uri, $quality = NULL) {
$webp = FALSE;
$toolkit = \Drupal::config('system.image')
->get('toolkit', FALSE);
if (!extension_loaded('imagick')) {
$toolkit = 'gd';
}
elseif ($toolkit == 'imagemagick' && !in_array('WEBP', Imagick::queryFormats())) {
$toolkit = 'gd';
}
if (is_null($quality)) {
$quality = $this->defaultQuality;
}
if ($toolkit == 'imagemagick') {
$webp = $this
->createImageMagickImage($uri, $quality);
}
else {
$sourceImage = $this->imageFactory
->get($uri, 'gd');
$toolkit = $sourceImage
->getToolkit();
$mimeType = $sourceImage
->getMimeType();
$sourceImage = $toolkit
->getResource();
if ($sourceImage !== NULL) {
$pathInfo = pathinfo($uri);
$destination = strtr('@directory/@filename.webp', [
'@directory' => $pathInfo['dirname'],
'@filename' => $pathInfo['filename'],
'@extension' => $pathInfo['extension'],
]);
imagesavealpha($sourceImage, TRUE);
imagealphablending($sourceImage, TRUE);
imagesavealpha($sourceImage, TRUE);
if (@imagewebp($sourceImage, $destination, $quality)) {
if (filesize($destination) % 2 == 1) {
file_put_contents($destination, "\0", FILE_APPEND);
}
@imagedestroy($sourceImage);
$webp = $destination;
}
else {
$error = $this
->t('Could not generate WebP image.');
$this->logger
->error($error);
}
}
else {
$error = $this
->t('Could not generate image resource from URI @uri.', [
'@uri' => $uri,
]);
$this->logger
->error($error);
}
}
return $webp;
}
public function deleteImageStyleDerivatives() {
try {
$this->fileSystem
->deleteRecursive(\Drupal::config('system.file')
->get('default_scheme') . '://styles');
} catch (FileException $e) {
$this->logger
->error($e
->getMessage());
$error = $this
->t('Could not delete image style directory while uninstalling WebP. You have to delete it manually.');
$this->logger
->error($error);
}
}
public function getWebpSrcset($srcset) {
return preg_replace('/\\.(png|jpg|jpeg)(\\?.*?)?(,| |$)/i', '.webp\\2\\3', $srcset);
}
private function createImageMagickImage($uri, $quality = NULL) {
$webp = FALSE;
$ImageMagickImg = $this->imageFactory
->get($uri, 'imagemagick');
$ImageMagickImg
->apply('convert', [
'extension' => 'webp',
'quality' => $quality,
]);
$pathInfo = pathinfo($uri);
$destination = $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '.webp';
if ($ImageMagickImg
->save($pathInfo['dirname'] . '/' . $pathInfo['filename'] . '.webp')) {
$webp = $destination;
$msg = $this
->t('Generated WebP image with Image Magick. Quality: ' . $quality . ' Destination:' . $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '.webp');
$this->logger
->info($msg);
}
else {
$error = $this
->t('Imagemagick issue: Could not generate WebP image.');
$this->logger
->error($error);
}
return $webp;
}
}