From 1868c63b937e666ad52e7b8c663b58477f20a03b Mon Sep 17 00:00:00 2001 From: Tim Moritz Date: Fri, 12 Jan 2024 10:56:39 +0100 Subject: [PATCH] Add .webp support --- bl-kernel/functions.php | 2 +- bl-kernel/helpers/image.class.php | 397 +++++++++++++++--------------- 2 files changed, 204 insertions(+), 195 deletions(-) diff --git a/bl-kernel/functions.php b/bl-kernel/functions.php index 1c160003..19f90a23 100644 --- a/bl-kernel/functions.php +++ b/bl-kernel/functions.php @@ -932,7 +932,7 @@ function transformImage($file, $imageDir, $thumbnailDir = false) // Generate Thumbnail if (!empty($thumbnailDir)) { - if (($fileExtension == 'svg') || ($fileExtension == 'webp')) { + if (($fileExtension == 'svg')) { Filesystem::symlink($image, $thumbnailDir . $nextFilename); } else { $Image = new Image(); diff --git a/bl-kernel/helpers/image.class.php b/bl-kernel/helpers/image.class.php index 0557c5db..f91d6baf 100644 --- a/bl-kernel/helpers/image.class.php +++ b/bl-kernel/helpers/image.class.php @@ -2,236 +2,245 @@ class Image { - private $image; - private $width; - private $height; - private $imageResized; + private $image; + private $width; + private $height; + private $imageResized; - public function setImage($fileName, $newWidth, $newHeight, $option="auto") - { - // *** Open up the file - $this->image = $this->openImage($fileName); + public function setImage($fileName, $newWidth, $newHeight, $option="auto") + { + // *** Open up the file + $this->image = $this->openImage($fileName); - // *** Get width and height - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); + // *** Get width and height + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); - $this->resizeImage($newWidth, $newHeight, $option); - } + $this->resizeImage($newWidth, $newHeight, $option); + } - public function saveImage($savePath, $imageQuality="100", $forceJPG=false, $forcePNG=false) - { - $extension = strtolower(pathinfo($savePath, PATHINFO_EXTENSION)); + public function saveImage($savePath, $imageQuality="100", $forceJPG=false, $forcePNG=false) + { + $extension = strtolower(pathinfo($savePath, PATHINFO_EXTENSION)); - // Remove the extension - $filename = substr($savePath, 0,strrpos($savePath,'.')); + // Remove the extension + $filename = substr($savePath, 0,strrpos($savePath,'.')); - $path_complete = $filename.'.'.$extension; + $path_complete = $filename.'.'.$extension; - if ($forcePNG) { - $extension = 'png'; - } elseif ($forceJPG) { - $extension = 'jpg'; - } + if ($forcePNG) { + $extension = 'png'; + } elseif ($forceJPG) { + $extension = 'jpg'; + } - switch ($extension) { - case 'jpg': - case 'jpeg': - // Checking for JPG support - if (imagetypes() & IMG_JPG) { - imagejpeg($this->imageResized, $path_complete, $imageQuality); - } - break; + switch ($extension) { + case 'jpg': + case 'jpeg': + // Checking for JPG support + if (imagetypes() & IMG_JPG) { + imagejpeg($this->imageResized, $path_complete, $imageQuality); + } + break; - case 'gif': - // Checking for GIF support - if (imagetypes() & IMG_GIF) { - imagegif($this->imageResized, $path_complete); - } - break; + case 'gif': + // Checking for GIF support + if (imagetypes() & IMG_GIF) { + imagegif($this->imageResized, $path_complete); + } + break; - case 'png': - // *** Scale quality from 0-100 to 0-9 - $scaleQuality = round(($imageQuality/100) * 9); + case 'png': + // *** Scale quality from 0-100 to 0-9 + $scaleQuality = round(($imageQuality/100) * 9); - // *** Invert quality setting as 0 is best, not 9 - $invertScaleQuality = 9 - $scaleQuality; + // *** Invert quality setting as 0 is best, not 9 + $invertScaleQuality = 9 - $scaleQuality; - // Checking for PNG support - if (imagetypes() & IMG_PNG) { - imagepng($this->imageResized, $path_complete, $invertScaleQuality); - } - break; + // Checking for PNG support + if (imagetypes() & IMG_PNG) { + imagepng($this->imageResized, $path_complete, $invertScaleQuality); + } + break; + case 'webp': + // Checking for JPG support + if (imagetypes() & IMG_WEBP) { + imagewebp($this->imageResized, $path_complete, $imageQuality); + } + break; - default: - // Fail extension detection - break; - } + default: + // Fail extension detection + break; + } - imagedestroy($this->imageResized); - } + imagedestroy($this->imageResized); + } - private function openImage($file) - { - // *** Get extension - $extension = strtolower(strrchr($file, '.')); + private function openImage($file) + { + // *** Get extension + $extension = strtolower(strrchr($file, '.')); - switch($extension) - { - case '.jpg': - case '.jpeg': - $img = imagecreatefromjpeg($file); - break; - case '.gif': - $img = imagecreatefromgif($file); - break; - case '.png': - $img = imagecreatefrompng($file); - break; - default: - $img = false; - break; - } - return $img; - } + switch($extension) + { + case '.jpg': + case '.jpeg': + $img = imagecreatefromjpeg($file); + break; + case '.gif': + $img = imagecreatefromgif($file); + break; + case '.png': + $img = imagecreatefrompng($file); + break; + case '.webp': + $img = imagecreatefromwebp($file); + break; + default: + $img = false; + break; + } + return $img; + } - private function resizeImage($newWidth, $newHeight, $option) - { - // *** Get optimal width and height - based on $option - $optionArray = $this->getDimensions($newWidth, $newHeight, $option); + private function resizeImage($newWidth, $newHeight, $option) + { + // *** Get optimal width and height - based on $option + $optionArray = $this->getDimensions($newWidth, $newHeight, $option); - $optimalWidth = $optionArray['optimalWidth']; - $optimalHeight = $optionArray['optimalHeight']; + $optimalWidth = $optionArray['optimalWidth']; + $optimalHeight = $optionArray['optimalHeight']; - // *** Resample - create image canvas of x, y size - $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); - imagealphablending($this->imageResized, false); - imagesavealpha($this->imageResized, true); - imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height); + // *** Resample - create image canvas of x, y size + $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); + imagealphablending($this->imageResized, false); + imagesavealpha($this->imageResized, true); + imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height); - // *** if option is 'crop', then crop too - if ($option == 'crop') { - $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight); - } - } + // *** if option is 'crop', then crop too + if ($option == 'crop') { + $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight); + } + } - private function getDimensions($newWidth, $newHeight, $option) - { + private function getDimensions($newWidth, $newHeight, $option) + { - if( ($this->width < $newWidth) and ($this->height < $newHeight) ) - { - return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height); - } + if( ($this->width < $newWidth) and ($this->height < $newHeight) ) + { + return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height); + } - switch ($option) - { - case 'exact': - $optimalWidth = $newWidth; - $optimalHeight= $newHeight; - break; - case 'portrait': - $optimalWidth = $this->getSizeByFixedHeight($newHeight); - $optimalHeight= $newHeight; - break; - case 'landscape': - $optimalWidth = $newWidth; - $optimalHeight= $this->getSizeByFixedWidth($newWidth); - break; - case 'auto': - $optionArray = $this->getSizeByAuto($newWidth, $newHeight); - $optimalWidth = $optionArray['optimalWidth']; - $optimalHeight = $optionArray['optimalHeight']; - break; - case 'crop': - $optionArray = $this->getOptimalCrop($newWidth, $newHeight); - $optimalWidth = $optionArray['optimalWidth']; - $optimalHeight = $optionArray['optimalHeight']; - break; - } + switch ($option) + { + case 'exact': + $optimalWidth = $newWidth; + $optimalHeight= $newHeight; + break; + case 'portrait': + $optimalWidth = $this->getSizeByFixedHeight($newHeight); + $optimalHeight= $newHeight; + break; + case 'landscape': + $optimalWidth = $newWidth; + $optimalHeight= $this->getSizeByFixedWidth($newWidth); + break; + case 'auto': + $optionArray = $this->getSizeByAuto($newWidth, $newHeight); + $optimalWidth = $optionArray['optimalWidth']; + $optimalHeight = $optionArray['optimalHeight']; + break; + case 'crop': + $optionArray = $this->getOptimalCrop($newWidth, $newHeight); + $optimalWidth = $optionArray['optimalWidth']; + $optimalHeight = $optionArray['optimalHeight']; + break; + } - return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); - } + return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); + } - private function getSizeByFixedHeight($newHeight) - { - $ratio = $this->width / $this->height; - $newWidth = $newHeight * $ratio; - return $newWidth; - } + private function getSizeByFixedHeight($newHeight) + { + $ratio = $this->width / $this->height; + $newWidth = $newHeight * $ratio; + return $newWidth; + } - private function getSizeByFixedWidth($newWidth) - { - $ratio = $this->height / $this->width; - $newHeight = $newWidth * $ratio; - return $newHeight; - } + private function getSizeByFixedWidth($newWidth) + { + $ratio = $this->height / $this->width; + $newHeight = $newWidth * $ratio; + return $newHeight; + } - private function getSizeByAuto($newWidth, $newHeight) - { - if ($this->height < $this->width) - // *** Image to be resized is wider (landscape) - { - $optimalWidth = $newWidth; - $optimalHeight= $this->getSizeByFixedWidth($newWidth); - } - elseif ($this->height > $this->width) - // *** Image to be resized is taller (portrait) - { - $optimalWidth = $this->getSizeByFixedHeight($newHeight); - $optimalHeight= $newHeight; - } - else - // *** Image to be resizerd is a square - { - if ($newHeight < $newWidth) { - $optimalWidth = $newWidth; - $optimalHeight= $this->getSizeByFixedWidth($newWidth); - } else if ($newHeight > $newWidth) { - $optimalWidth = $this->getSizeByFixedHeight($newHeight); - $optimalHeight= $newHeight; - } else { - // *** Sqaure being resized to a square - $optimalWidth = $newWidth; - $optimalHeight= $newHeight; - } - } + private function getSizeByAuto($newWidth, $newHeight) + { + if ($this->height < $this->width) + // *** Image to be resized is wider (landscape) + { + $optimalWidth = $newWidth; + $optimalHeight= $this->getSizeByFixedWidth($newWidth); + } + elseif ($this->height > $this->width) + // *** Image to be resized is taller (portrait) + { + $optimalWidth = $this->getSizeByFixedHeight($newHeight); + $optimalHeight= $newHeight; + } + else + // *** Image to be resizerd is a square + { + if ($newHeight < $newWidth) { + $optimalWidth = $newWidth; + $optimalHeight= $this->getSizeByFixedWidth($newWidth); + } else if ($newHeight > $newWidth) { + $optimalWidth = $this->getSizeByFixedHeight($newHeight); + $optimalHeight= $newHeight; + } else { + // *** Sqaure being resized to a square + $optimalWidth = $newWidth; + $optimalHeight= $newHeight; + } + } - return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); - } + return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); + } - private function getOptimalCrop($newWidth, $newHeight) - { + private function getOptimalCrop($newWidth, $newHeight) + { - $heightRatio = $this->height / $newHeight; - $widthRatio = $this->width / $newWidth; + $heightRatio = $this->height / $newHeight; + $widthRatio = $this->width / $newWidth; - if ($heightRatio < $widthRatio) { - $optimalRatio = $heightRatio; - } else { - $optimalRatio = $widthRatio; - } + if ($heightRatio < $widthRatio) { + $optimalRatio = $heightRatio; + } else { + $optimalRatio = $widthRatio; + } - $optimalHeight = $this->height / $optimalRatio; - $optimalWidth = $this->width / $optimalRatio; + $optimalHeight = $this->height / $optimalRatio; + $optimalWidth = $this->width / $optimalRatio; - return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); - } + return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); + } - private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight) - { - // *** Find center - this will be used for the crop - $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 ); - $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 ); + private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight) + { + // *** Find center - this will be used for the crop + $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 ); + $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 ); - $crop = $this->imageResized; - //imagedestroy($this->imageResized); + $crop = $this->imageResized; + //imagedestroy($this->imageResized); - // *** Now crop from center to exact requested size - $this->imageResized = imagecreatetruecolor($newWidth , $newHeight); - imagealphablending($this->imageResized, false); - imagesavealpha($this->imageResized, true); - imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight); - } + // *** Now crop from center to exact requested size + $this->imageResized = imagecreatetruecolor($newWidth , $newHeight); + imagealphablending($this->imageResized, false); + imagesavealpha($this->imageResized, true); + imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight); + } }