imageSize = getimagesize($sourcePath); $this->outputWidth = $this->cropWidth = $this->imageSize[0]; $this->outputHeight = $this->cropHeight = $this->imageSize[1]; $this->destinationResource = imagecreatetruecolor($this->outputWidth, $this->outputHeight); list($creationFunction, $outputFunction) = $this->functionNames(); $this->sourceResource = $creationFunction($sourcePath); $this->outputFunction = $outputFunction; } /** * Set up the appropriate image handling functions based on the original image's mime type * @return array */ protected function functionNames() { $size = $this->imageSize; switch ($size['mime']) { case 'image/gif': // We will be converting GIFs to PNGs to avoid transparency issues when resizing GIFs // This is maybe not the ideal solution, but IE6 can suck it $creationFunction = 'ImageCreateFromGif'; $outputFunction = 'ImagePng'; break; case 'image/x-png': case 'image/png': $creationFunction = 'ImageCreateFromPng'; $outputFunction = 'ImagePng'; $this->qualityMultiplier = 0.01; break; default: $creationFunction = 'ImageCreateFromJpeg'; $outputFunction = 'ImageJpeg'; break; } return [ $creationFunction, $outputFunction, ]; } public static function resize($sourcePath, $width, $height, $offsetX, $offsetY, $cropWidth, $cropHeight) { $instance = new static($sourcePath); $instance->outputWidth($width); $instance->outputHeight($height); $instance->offsetX($offsetX); $instance->offsetY($offsetY); $instance->cropWidth($cropWidth); $instance->cropHeight($cropHeight); $instance->copyResampled($instance->sourceResource, $instance->destinationResource); return $instance; } public function outputWidth($width, $reset = true) { $this->outputWidth = $width; if ($reset) { $this->setDestination(); } return $this; } protected function setDestination() { $this->destinationResource = imageCreateTruecolor($this->outputWidth, $this->outputHeight); $this->preserveAlfa(); if ($this->mustCopy) { call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]); } } private function preserveAlfa() { if (in_array($this->imageSize['mime'], array('image/gif', 'image/png'))) { // If this is a GIF or a PNG, we need to set up transparency imageAlphaBlending($this->destinationResource, false); imageSaveAlpha($this->destinationResource, true); } } public function outputHeight($height, $reset = true) { $this->outputHeight = $height; if ($reset) { $this->setDestination(); } return $this; } public function offsetX($value) { $this->offsetX = $value; if ($this->mustCopy) { call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]); } return $this; } public function offsetY($value) { $this->offsetY = $value; if ($this->mustCopy) { call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]); } return $this; } public function cropWidth($width) { $this->cropWidth = $width; if ($this->mustCopy) { call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]); } return $this; } public function cropHeight($height) { $this->cropHeight = $height; if ($this->mustCopy) { call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]); } return $this; } public function copyResampled($source, $destination) { $this->mustCopy = 'copyResampled'; imageCopyResampled( $destination, $source, 0, 0, $this->offsetX, $this->offsetY, $this->outputWidth, $this->outputHeight, $this->cropWidth, $this->cropHeight); return $this; } public static function watermark($sourcePath, $watermarkPath, $position = false) { if (!$position) { $position = static::WM_POS_CENTER_CENTER; } $instance = new static($sourcePath); $instance->setWatermark($watermarkPath); $watermarkSizes = getimagesize($watermarkPath); $instance->copy($instance->sourceResource, $instance->destinationResource); $offsets = $instance->calculatePosition($position, ['width' => $watermarkSizes[0], 'height' => $watermarkSizes[1]]); $instance->mustCopy = false; $instance->offsetX($offsets['x']); $instance->offsetY($offsets['y']); $instance->outputWidth($watermarkSizes[0], false); $instance->outputHeight($watermarkSizes[1], false); $instance->copy($instance->watermarkSource, $instance->destinationResource); return $instance; } protected function setWatermark($watermarkPath) { $this->watermarkSource = imagecreatefrompng($watermarkPath); return $this; } public function copy($source, $destination) { $this->mustCopy = 'copy'; imagecopy( $destination, $source, $this->offsetX, $this->offsetY, 0, 0, $this->outputWidth, $this->outputHeight ); return $this; } protected function calculatePosition($position, $wmSizes = ['width' => 0, 'height' => 0]) { return call_user_func_array([$this, 'pos' . ucfirst($position)], $wmSizes); } public function quality($quality) { $this->quality = $quality; return $this; } public function output($destination = null) { $outputFunction = $this->outputFunction; $path = dirname($destination); if (!file_exists($path)) { mkdir($path, 0777, true); } $outputFunction($this->destinationResource, $destination, $this->quality * $this->qualityMultiplier); } protected function posLeftTop($width, $height) { return [ 'x' => 10, 'y' => 10, ]; } protected function posTop($width, $height) { return [ 'x' => $this->outputWidth / 2 - $width / 2, 'y' => 10, ]; } protected function posRightTop($width, $height) { return [ 'x' => $this->outputWidth - $width - 10, 'y' => 10, ]; } protected function posLeftCenter($width, $height) { return [ 'x' => 10, 'y' => $this->outputHeight / 2 - $height / 2, ]; } protected function posCenter($width, $height) { return [ 'x' => $this->outputWidth / 2 - $width / 2, 'y' => $this->outputHeight / 2 - $height / 2, ]; } protected function posRightCenter($width, $height) { return [ 'x' => $this->outputWidth - $width - 10, 'y' => $this->outputHeight / 2 - $height / 2, ]; } protected function posLeftBottom($width, $height) { return [ 'x' => 10, 'y' => $this->outputHeight - $height - 10, ]; } protected function posBottom($width, $height) { return [ 'x' => $this->outputWidth / 2 - $width / 2, 'y' => $this->outputHeight - $height - 10, ]; } protected function posRightBottom($width, $height) { return [ 'x' => $this->outputWidth - $width - 10, 'y' => $this->outputHeight - $height - 10, ]; } }