image = $this->openImage($fileName); // *** Check if image was opened successfully if ($this->image === false) { return false; } // *** Get width and height $this->width = imagesx($this->image); $this->height = imagesy($this->image); $this->resizeImage($newWidth, $newHeight, $option); return true; } 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,'.')); if ($forcePNG) { $extension = 'png'; } elseif ($forceJPG) { $extension = 'jpg'; } $path_complete = $filename.'.'.$extension; 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 '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; // Checking for PNG support if (imagetypes() & IMG_PNG) { imagepng($this->imageResized, $path_complete, $invertScaleQuality); } break; case 'webp': // Checking for WEBP support if (imagetypes() & IMG_WEBP) { imagewebp($this->imageResized, $path_complete, $imageQuality); } break; default: // Fail extension detection break; } } private function openImage($file) { // *** Get extension $extension = strtolower(strrchr($file, '.')); // GD may be compiled without support for some formats (often WebP, and // sometimes JPEG on minimal builds). Guard each decoder with both a // runtime capability check and a function_exists() check to avoid a // fatal "call to undefined function" on stripped builds. $types = imagetypes(); switch($extension) { case '.jpg': case '.jpeg': if (!($types & IMG_JPG) || !function_exists('imagecreatefromjpeg')) { return false; } $img = imagecreatefromjpeg($file); break; case '.gif': if (!($types & IMG_GIF) || !function_exists('imagecreatefromgif')) { return false; } $img = imagecreatefromgif($file); break; case '.png': if (!($types & IMG_PNG) || !function_exists('imagecreatefrompng')) { return false; } $img = imagecreatefrompng($file); break; case '.webp': if (!($types & IMG_WEBP) || !function_exists('imagecreatefromwebp')) { return false; } $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); $optimalWidth = (int) $optionArray['optimalWidth']; $optimalHeight = (int) $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); // *** if option is 'crop', then crop too if ($option == 'crop') { $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight); } } private function getDimensions($newWidth, $newHeight, $option) { 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; default: $optionArray = $this->getSizeByAuto($newWidth, $newHeight); $optimalWidth = $optionArray['optimalWidth']; $optimalHeight = $optionArray['optimalHeight']; break; } return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); } 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 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); } private function getOptimalCrop($newWidth, $newHeight) { $heightRatio = $this->height / $newHeight; $widthRatio = $this->width / $newWidth; if ($heightRatio < $widthRatio) { $optimalRatio = $heightRatio; } else { $optimalRatio = $widthRatio; } $optimalHeight = $this->height / $optimalRatio; $optimalWidth = $this->width / $optimalRatio; return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); } private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight) { // *** Find center - this will be used for the crop $cropStartX = (int) (( $optimalWidth / 2) - ( $newWidth /2 )); $cropStartY = (int) (( $optimalHeight/ 2) - ( $newHeight/2 )); $crop = $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); } }