Skip to content

Instantly share code, notes, and snippets.

@Arifursdev
Created June 21, 2023 16:18
Show Gist options
  • Save Arifursdev/447a6431193f67bf9918b26adc9742af to your computer and use it in GitHub Desktop.
Save Arifursdev/447a6431193f67bf9918b26adc9742af to your computer and use it in GitHub Desktop.
<?php
class ImageResizer {
private $cacheDir;
private $cacheDirUri;
/**
* WPImageResizer constructor.
*
* @param string $cacheDir The cache directory where resized images will be stored
* @param string $cacheDirUri The URL path to the cache directory
*/
public function __construct($cacheDir, $cacheDirUri) {
$this->cacheDir = $cacheDir;
$this->cacheDirUri = $cacheDirUri;
}
/**
* Resize an image and generate the <img> tag with srcset attribute for the resized images.
*
* @param string $imageUrl The URL of the original image
* @param array $sizes An array of widths for the resized images
* @return string The <img> tag with srcset attribute for the resized images
* @throws \Exception If the image format is unsupported
*/
public function renderOptimizedImage($imageUrl, $sizes) {
$resizedImages = [];
foreach ($sizes as $width) {
$resizedImagePath = $this->cacheDir . '/' . $this->getCacheFilename($imageUrl, $width);
if (!file_exists($resizedImagePath)) {
$this->createResizedImage($imageUrl, $resizedImagePath, $width);
}
$resizedImages[] = $this->cacheDirUri . '/' . $this->getCacheFilename($imageUrl, $width);
}
return $this->generateImgTag($resizedImages, $sizes);
}
/**
* Create a resized image based on the specified width.
*
* @param string $imageUrl The URL of the original image
* @param string $resizedImagePath The path where the resized image will be saved
* @param int $width The desired width of the resized image
* @throws \Exception If the image format is unsupported
*/
private function createResizedImage($imageUrl, $resizedImagePath, $width) {
list($originalWidth, $originalHeight, $extension) = getimagesize($imageUrl);
// Calculate the height based on the aspect ratio
$height = (int)(($width / $originalWidth) * $originalHeight);
// Load the image based on the file extension
switch ($extension) {
case IMAGETYPE_JPEG:
$sourceImage = imagecreatefromjpeg($imageUrl);
break;
case IMAGETYPE_PNG:
$sourceImage = imagecreatefrompng($imageUrl);
break;
case IMAGETYPE_GIF:
$sourceImage = imagecreatefromgif($imageUrl);
break;
default:
throw new \Exception('Unsupported image format');
}
// Create a new blank image with the desired dimensions
$resizedImage = imagecreatetruecolor($width, $height);
// Preserve transparency for PNG images
if ($extension === IMAGETYPE_PNG) {
imagealphablending($resizedImage, false);
imagesavealpha($resizedImage, true);
$transparent = imagecolorallocate($resizedImage, 0, 0, 0);
imagecolortransparent($resizedImage, $transparent);
imagefilledrectangle($resizedImage, 0, 0, $width, $height, $transparent);
}
// Set the image interpolation method to Bicubic for better quality
imagesetinterpolation($resizedImage, IMG_BICUBIC);
// Resize the image
imagecopyresampled($resizedImage, $sourceImage, 0, 0, 0, 0, $width, $height, $originalWidth, $originalHeight);
// Save the resized image
switch ($extension) {
case IMAGETYPE_JPEG:
// Adjust the JPEG quality to your desired value (80 is just an example)
imagejpeg($resizedImage, $resizedImagePath, 80);
break;
case IMAGETYPE_PNG:
imagepng($resizedImage, $resizedImagePath);
break;
case IMAGETYPE_GIF:
imagegif($resizedImage, $resizedImagePath);
break;
}
imagedestroy($sourceImage);
imagedestroy($resizedImage);
}
/**
* Generate the <img> tag with srcset attribute for the resized images.
*
* @param array $resizedImages An array of paths to the resized images
* @param array $sizes An array of widths for the resized images
* @return string The <img> tag with srcset attribute
*/
private function generateImgTag($resizedImages, $sizes) {
$imgTag = '<img src="' . $resizedImages[0] . '" srcset="';
foreach ($resizedImages as $index => $resizedImage) {
$width = $sizes[$index];
$imgTag .= $resizedImage . ' ' . $width . 'w, ';
}
$imgTag = rtrim($imgTag, ', ') . '">';
return $imgTag;
}
/**
* Get the cache filename for the resized image.
*
* @param string $imageUrl The URL of the original image
* @param int $width The width of the resized image
* @return string The cache filename
*/
private function getCacheFilename($imageUrl, $width) {
$pathInfo = pathinfo($imageUrl);
$extension = strtolower($pathInfo['extension']);
$filename = $pathInfo['filename'];
return $filename . '-' . $width . 'x.' . $extension;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment