rlm@3: rlm@3: * rlm@3: * @link http://www.bin-co.com/php/scripts/classes/gd_image/ Based on work by "Binny V A" rlm@3: */ rlm@3: rlm@3: class Image { rlm@3: /** rlm@3: * The path to the image file rlm@3: * rlm@3: * @var string rlm@3: */ rlm@3: private $file; rlm@3: /** rlm@3: * The image resource rlm@3: * rlm@3: * @var resource rlm@3: */ rlm@3: private $image; rlm@3: /** rlm@3: * Metadata regarding the image rlm@3: * rlm@3: * @var array rlm@3: */ rlm@3: private $meta; rlm@3: rlm@3: /** rlm@3: * @param string $file The path to the image file rlm@3: */ rlm@3: public function __construct($file){ rlm@3: $file = realpath($file); rlm@3: if(!file_exists($file)) rlm@3: return; rlm@3: rlm@3: $this->file = $file; rlm@3: $img = getimagesize($file); rlm@3: rlm@3: $this->meta = array( rlm@3: 'width' => $img[0], rlm@3: 'height' => $img[1], rlm@3: 'mime' => $img['mime'], rlm@3: 'ext' => end(explode('/', $img['mime'])), rlm@3: ); rlm@3: if($this->meta['ext']=='jpg') rlm@3: $this->meta['ext'] = 'jpeg'; rlm@3: rlm@3: if(!in_array($this->meta['ext'], array('gif', 'png', 'jpeg'))) rlm@3: return; rlm@3: rlm@3: if(in_array($this->meta['ext'], array('gif', 'png'))){ rlm@3: $this->image = $this->create(); rlm@3: rlm@3: $fn = 'imagecreatefrom'.$this->meta['ext']; rlm@3: $original = $fn($file); rlm@3: imagecopyresampled($this->image, $original, 0, 0, 0, 0, $this->meta['width'], $this->meta['height'], $this->meta['width'], $this->meta['height']); rlm@3: }else{ rlm@3: $this->image = imagecreatefromjpeg($file); rlm@3: } rlm@3: } rlm@3: rlm@3: public function __destruct(){ rlm@3: if(!empty($this->image)) imagedestroy($this->image); rlm@3: } rlm@3: rlm@3: /** rlm@3: * Returns the size of the image rlm@3: * rlm@3: * @return array rlm@3: */ rlm@3: public function getSize(){ rlm@3: return array( rlm@3: 'width' => $this->meta['width'], rlm@3: 'height' => $this->meta['height'], rlm@3: ); rlm@3: } rlm@3: rlm@3: /** rlm@3: * Creates a new, empty image with the desired size rlm@3: * rlm@3: * @param int $x rlm@3: * @param int $y rlm@3: * @param string $ext rlm@3: * @return resource rlm@3: */ rlm@3: private function create($x = null, $y = null, $ext = null){ rlm@3: if(!$x) $x = $this->meta['width']; rlm@3: if(!$y) $y = $this->meta['height']; rlm@3: rlm@3: $image = imagecreatetruecolor($x, $y); rlm@3: if(!$ext) $ext = $this->meta['ext']; rlm@3: if($ext=='png'){ rlm@3: imagealphablending($image, false); rlm@3: imagefilledrectangle($image, 0, 0, $x, $y, imagecolorallocatealpha($image, 0, 0, 0, 127)); rlm@3: } rlm@3: rlm@3: return $image; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Replaces the image resource with the given parameter rlm@3: * rlm@3: * @param resource $new rlm@3: */ rlm@3: private function set($new){ rlm@3: imagedestroy($this->image); rlm@3: $this->image = $new; rlm@3: rlm@3: $this->meta['width'] = imagesx($this->image); rlm@3: $this->meta['height'] = imagesy($this->image); rlm@3: } rlm@3: rlm@3: /** rlm@3: * Returns the path to the image file rlm@3: * rlm@3: * @return string rlm@3: */ rlm@3: public function getPathname(){ rlm@3: return $this->file; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Rotates the image by the given angle rlm@3: * rlm@3: * @param int $angle rlm@3: * @param array $bgcolor An indexed array with red/green/blue/alpha values rlm@3: * @return Image rlm@3: */ rlm@3: public function rotate($angle, $bgcolor = null){ rlm@3: if(empty($this->image) || !$angle || $angle>=360) return $this; rlm@3: rlm@3: $this->set(imagerotate($this->image, $angle, is_array($bgcolor) ? imagecolorallocatealpha($this->image, $bgcolor[0], $bgcolor[1], $bgcolor[2], !empty($bgcolor[3]) ? $bgcolor[3] : null) : $bgcolor)); rlm@3: rlm@3: return $this; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Resizes the image to the given size, automatically calculates rlm@3: * the new ratio if parameter {@link $ratio} is set to true rlm@3: * rlm@3: * @param int $x rlm@3: * @param int $y rlm@3: * @param bool $ratio rlm@3: * @return Image rlm@3: */ rlm@3: public function resize($x = null, $y = null, $ratio = true){ rlm@3: if(empty($this->image) || (!$x && !$y)) return $this; rlm@3: rlm@3: if(!$y) $y = $ratio ? $this->meta['height']*$x/$this->meta['width'] : $this->meta['height']; rlm@3: if(!$x) $x = $ratio ? $this->meta['width']*$y/$this->meta['height'] : $this->meta['width']; rlm@3: rlm@3: $new = $this->create($x, $y); rlm@3: imagecopyresampled($new, $this->image, 0, 0, 0, 0, $x, $y, $this->meta['width'], $this->meta['height']); rlm@3: $this->set($new); rlm@3: rlm@3: return $this; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Crops the image. The values are given like margin/padding values in css rlm@3: * rlm@3: * Example rlm@3: * rlm@3: * rlm@3: * @param int $top rlm@3: * @param int $right rlm@3: * @param int $bottom rlm@3: * @param int $left rlm@3: * @return Image rlm@3: */ rlm@3: public function crop($top, $right = null, $bottom = null, $left = null){ rlm@3: if(empty($this->image)) return $this; rlm@3: rlm@3: if(!is_numeric($right) && !is_numeric($bottom) && !is_numeric($left)) rlm@3: $right = $bottom = $left = $top; rlm@3: rlm@3: if(!is_numeric($bottom) && !is_numeric($left)){ rlm@3: $bottom = $top; rlm@3: $left = $right; rlm@3: } rlm@3: rlm@3: if(!is_numeric($left)) rlm@3: $left = $right; rlm@3: rlm@3: $x = $this->meta['width']-$left-$right; rlm@3: $y = $this->meta['height']-$top-$bottom; rlm@3: rlm@3: if($x<0 || $y<0) return $this; rlm@3: rlm@3: $new = $this->create($x, $y); rlm@3: imagecopy($new, $this->image, 0, 0, $left, $top, $x, $y); rlm@3: $this->set($new); rlm@3: rlm@3: return $this; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Flips the image horizontally or vertically. To Flip both just use ->rotate(180) rlm@3: * rlm@3: * @see Image::rotate() rlm@3: * @param string $type Either horizontal or vertical rlm@3: * @return Image rlm@3: */ rlm@3: public function flip($type){ rlm@3: if(empty($this->image) || !in_array($type, array('horizontal', 'vertical'))) return $this; rlm@3: rlm@3: $new = $this->create(); rlm@3: rlm@3: if($type=='horizontal') rlm@3: for($x=0;$x<$this->meta['width'];$x++) rlm@3: imagecopy($new, $this->image, $this->meta['width']-$x-1, 0, $x, 0, 1, $this->meta['height']); rlm@3: elseif($type=='vertical') rlm@3: for($y=0;$y<$this->meta['height'];$y++) rlm@3: imagecopy($new, $this->image, 0, $this->meta['height']-$y-1, 0, $y, $this->meta['width'], 1); rlm@3: rlm@3: $this->set($new); rlm@3: rlm@3: return $this; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Stores the image in the desired directory or outputs it rlm@3: * rlm@3: * @param string $ext rlm@3: * @param string $file rlm@3: */ rlm@3: private function process($ext = null, $file = null){ rlm@3: if(!$ext) $ext = $this->meta['ext']; rlm@3: rlm@3: if($ext=='png') imagesavealpha($this->image, true); rlm@3: $fn = 'image'.$ext; rlm@3: $fn($this->image, $file); rlm@3: rlm@3: // If there is a new filename change the internal name too rlm@3: if($file) $this->file = $file; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Saves the image to the given path rlm@3: * rlm@3: * @param string $file Leave empty to replace the original file rlm@3: * @return Image rlm@3: */ rlm@3: public function save($file = null){ rlm@3: if(empty($this->image)) return $this; rlm@3: rlm@3: if(!$file) $file = $this->file; rlm@3: rlm@3: $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); rlm@3: if(!$ext){ rlm@3: $file .= '.'.$this->meta['ext']; rlm@3: $ext = $this->meta['ext']; rlm@3: } rlm@3: rlm@3: if($ext=='jpg') $ext = 'jpeg'; rlm@3: rlm@3: if(!in_array($ext, array('png', 'jpeg', 'gif'))) rlm@3: return $this; rlm@3: rlm@3: $this->process($ext, $file); rlm@3: rlm@3: return $this; rlm@3: } rlm@3: rlm@3: /** rlm@3: * Outputs the manipulated image rlm@3: * rlm@3: * @return Image rlm@3: */ rlm@3: public function show(){ rlm@3: if(empty($this->image)) return $this; rlm@3: rlm@3: header('Content-type: '.$this->meta['mime']); rlm@3: $this->process(); rlm@3: rlm@3: return $this; rlm@3: } rlm@3: rlm@3: }