<?php
namespace Engine\GenDocument\Image; class ThumbnailCreator { protected $thumbDir; protected $thumbFormat = 'jpg'; protected $maxWidth = 250; protected $maxHeight = 250; protected $thumbQuality = 7; public function setThumbDir($thumbDir) { if (!\Engine\Dir::check($thumbDir)) { \Engine\Dir::create($thumbDir); } $this->thumbDir = $thumbDir; } public function setThumbFormat($thumbFormat) { if ($thumbFormat!='png' && $thumbFormat!='jpg'){ throw new Exception("Invalid thumbnail format {$thumbFormat}"); } $this->thumbFormat = $thumbFormat; } public function setMaxWidth($maxWidth) { if (!$maxWidth || $maxWidth<0 || !is_numeric($maxWidth)) { throw new Exception("Invalid max width {$maxWidth}"); } $this->maxWidth = $maxWidth; } public function setMaxHeight($maxHeight) { if (!$maxHeight || $maxHeight<0 || !is_numeric($maxHeight)) { throw new Exception("Invalid max height {$maxHeight}"); } $this->maxHeight = $maxHeight; } public function setThumbQuality($thumbQuality) { if ($thumbQuality<0 or $thumbQuality>10) { throw new Exception("Invalid thumbnail quality {$thumbQuality}"); } $this->thumbQuality = $thumbQuality; } protected function generateThumbnailPath($source) { $dest = $this->thumbDir.sprintf("%s-%s%d%d%d-%d.%s", preg_replace("/[^a-z0-9]/i", "", __CLASS__), md5($source), $this->maxWidth, $this->maxHeight, $this->thumbQuality, filemtime($source), $this->thumbFormat ); return $dest; } protected function createThumbnail($source, $dest) { $extension = strtolower(pathinfo($source, PATHINFO_EXTENSION)); $imagetype = exif_imagetype($source); $src = null; $is_image = false; switch ($imagetype) { case IMAGETYPE_GIF: $src = @imagecreatefromgif($source); if ($src) { $is_image = true; } else { throw new Exception("Invalid GIF file"); } break; case IMAGETYPE_JPEG: $src = @imagecreatefromjpeg($source); if ($src) { $is_image = true; } else { throw new Exception("Invalid JPEG file"); } break; case IMAGETYPE_PNG: $src = @imagecreatefrompng($source); if ($src) { $is_image = true; } else { throw new Exception("Invalid PNG file"); } break; default: throw new Exception("Unsupported image type: {$extension}"); } if (!$is_image) { throw new Exception("Invalid source file extension {$extension}"); } list($width, $height) = getimagesize($source); if ($this->maxWidth<$width) { $newWidth = $this->maxWidth; $newHeight = (int)(($newWidth/$width)*$height); } elseif ($this->maxHeight<$height) { $newHeight = $this->maxHeight; $newWidth = (int)(($newHeight/$height)*$width); } else { $newWidth = $width; $newHeight = $height; } $tmp = imagecreatetruecolor($newWidth, $newHeight); if ($this->thumbFormat=='jpg') { $white = imagecolorallocate($tmp, 255, 255, 255); imagefilledrectangle($tmp, 0, 0, $newWidth, $newHeight, $white); imagecopyresampled($tmp,$src,0,0,0,0,$newWidth,$newHeight,$width,$height); imagejpeg($tmp, $dest, $this->thumbQuality*10); } elseif ($this->thumbFormat=='png') { imagealphablending($tmp, false); imagesavealpha($tmp, true); $transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127); imagefilledrectangle($tmp, 0, 0, $newWidth, $newHeight, $transparent); imagecopyresampled($tmp,$src,0,0,0,0,$newWidth,$newHeight,$width,$height); imagepng($tmp, $dest, 9); } else { throw new Exception("Implementation not available for this format {$this->thumbFormat}"); } imagedestroy($src); imagedestroy($tmp); return [$newWidth, $newHeight]; } public function createCached($source) { if (!is_file($source) || !is_readable($source)) { throw new Exception("Invalid source file {$source}"); } list($originalWidth, $originalHeight) = getimagesize($source); $originalSize = filesize($source); $originalName = \Engine\File::getNameFull($source); $originalMtime = filemtime($source); $dest = $this->generateThumbnailPath($source); $cacheHit = false; if (is_file($dest)) { $cacheHit = true; list($thumbWidth, $thumbHeight) = getimagesize($dest); } else { $cacheHit = false; list($thumbWidth, $thumbHeight) = $this->createThumbnail($source, $dest); } $thumbInfo = [ 'originalWidth' => $originalWidth, 'originalHeight' => $originalHeight, 'originalSize' => $originalSize, 'originalName' => $originalName, 'originalMtime' => $originalMtime, 'file' => $dest, 'width' => $thumbWidth, 'height' => $thumbHeight, 'cacheHit' => $cacheHit, ]; return $thumbInfo; } }