annotate e2gallerypro/e2upload/Backend/Image.php @ 28:118cb614cf18 judyates tip

judy bio.
author Robert McIntyre <rlm@mit.edu>
date Tue, 29 Dec 2015 16:26:18 -0800
parents 3f6b44aa6b35
children
rev   line source
rlm@3 1 <?php
rlm@3 2 /**
rlm@3 3 * Styx::Image - Provides an Interface to the GD-Library for image manipulation
rlm@3 4 *
rlm@3 5 * @package Styx
rlm@3 6 * @subpackage Utility
rlm@3 7 *
rlm@3 8 * @license MIT-style License
rlm@3 9 * @author Christoph Pojer <christoph.pojer@gmail.com>
rlm@3 10 *
rlm@3 11 * @link http://www.bin-co.com/php/scripts/classes/gd_image/ Based on work by "Binny V A"
rlm@3 12 */
rlm@3 13
rlm@3 14 class Image {
rlm@3 15 /**
rlm@3 16 * The path to the image file
rlm@3 17 *
rlm@3 18 * @var string
rlm@3 19 */
rlm@3 20 private $file;
rlm@3 21 /**
rlm@3 22 * The image resource
rlm@3 23 *
rlm@3 24 * @var resource
rlm@3 25 */
rlm@3 26 private $image;
rlm@3 27 /**
rlm@3 28 * Metadata regarding the image
rlm@3 29 *
rlm@3 30 * @var array
rlm@3 31 */
rlm@3 32 private $meta;
rlm@3 33
rlm@3 34 /**
rlm@3 35 * @param string $file The path to the image file
rlm@3 36 */
rlm@3 37 public function __construct($file){
rlm@3 38 $file = realpath($file);
rlm@3 39 if(!file_exists($file))
rlm@3 40 return;
rlm@3 41
rlm@3 42 $this->file = $file;
rlm@3 43 $img = getimagesize($file);
rlm@3 44
rlm@3 45 $this->meta = array(
rlm@3 46 'width' => $img[0],
rlm@3 47 'height' => $img[1],
rlm@3 48 'mime' => $img['mime'],
rlm@3 49 'ext' => end(explode('/', $img['mime'])),
rlm@3 50 );
rlm@3 51 if($this->meta['ext']=='jpg')
rlm@3 52 $this->meta['ext'] = 'jpeg';
rlm@3 53
rlm@3 54 if(!in_array($this->meta['ext'], array('gif', 'png', 'jpeg')))
rlm@3 55 return;
rlm@3 56
rlm@3 57 if(in_array($this->meta['ext'], array('gif', 'png'))){
rlm@3 58 $this->image = $this->create();
rlm@3 59
rlm@3 60 $fn = 'imagecreatefrom'.$this->meta['ext'];
rlm@3 61 $original = $fn($file);
rlm@3 62 imagecopyresampled($this->image, $original, 0, 0, 0, 0, $this->meta['width'], $this->meta['height'], $this->meta['width'], $this->meta['height']);
rlm@3 63 }else{
rlm@3 64 $this->image = imagecreatefromjpeg($file);
rlm@3 65 }
rlm@3 66 }
rlm@3 67
rlm@3 68 public function __destruct(){
rlm@3 69 if(!empty($this->image)) imagedestroy($this->image);
rlm@3 70 }
rlm@3 71
rlm@3 72 /**
rlm@3 73 * Returns the size of the image
rlm@3 74 *
rlm@3 75 * @return array
rlm@3 76 */
rlm@3 77 public function getSize(){
rlm@3 78 return array(
rlm@3 79 'width' => $this->meta['width'],
rlm@3 80 'height' => $this->meta['height'],
rlm@3 81 );
rlm@3 82 }
rlm@3 83
rlm@3 84 /**
rlm@3 85 * Creates a new, empty image with the desired size
rlm@3 86 *
rlm@3 87 * @param int $x
rlm@3 88 * @param int $y
rlm@3 89 * @param string $ext
rlm@3 90 * @return resource
rlm@3 91 */
rlm@3 92 private function create($x = null, $y = null, $ext = null){
rlm@3 93 if(!$x) $x = $this->meta['width'];
rlm@3 94 if(!$y) $y = $this->meta['height'];
rlm@3 95
rlm@3 96 $image = imagecreatetruecolor($x, $y);
rlm@3 97 if(!$ext) $ext = $this->meta['ext'];
rlm@3 98 if($ext=='png'){
rlm@3 99 imagealphablending($image, false);
rlm@3 100 imagefilledrectangle($image, 0, 0, $x, $y, imagecolorallocatealpha($image, 0, 0, 0, 127));
rlm@3 101 }
rlm@3 102
rlm@3 103 return $image;
rlm@3 104 }
rlm@3 105
rlm@3 106 /**
rlm@3 107 * Replaces the image resource with the given parameter
rlm@3 108 *
rlm@3 109 * @param resource $new
rlm@3 110 */
rlm@3 111 private function set($new){
rlm@3 112 imagedestroy($this->image);
rlm@3 113 $this->image = $new;
rlm@3 114
rlm@3 115 $this->meta['width'] = imagesx($this->image);
rlm@3 116 $this->meta['height'] = imagesy($this->image);
rlm@3 117 }
rlm@3 118
rlm@3 119 /**
rlm@3 120 * Returns the path to the image file
rlm@3 121 *
rlm@3 122 * @return string
rlm@3 123 */
rlm@3 124 public function getPathname(){
rlm@3 125 return $this->file;
rlm@3 126 }
rlm@3 127
rlm@3 128 /**
rlm@3 129 * Rotates the image by the given angle
rlm@3 130 *
rlm@3 131 * @param int $angle
rlm@3 132 * @param array $bgcolor An indexed array with red/green/blue/alpha values
rlm@3 133 * @return Image
rlm@3 134 */
rlm@3 135 public function rotate($angle, $bgcolor = null){
rlm@3 136 if(empty($this->image) || !$angle || $angle>=360) return $this;
rlm@3 137
rlm@3 138 $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 139
rlm@3 140 return $this;
rlm@3 141 }
rlm@3 142
rlm@3 143 /**
rlm@3 144 * Resizes the image to the given size, automatically calculates
rlm@3 145 * the new ratio if parameter {@link $ratio} is set to true
rlm@3 146 *
rlm@3 147 * @param int $x
rlm@3 148 * @param int $y
rlm@3 149 * @param bool $ratio
rlm@3 150 * @return Image
rlm@3 151 */
rlm@3 152 public function resize($x = null, $y = null, $ratio = true){
rlm@3 153 if(empty($this->image) || (!$x && !$y)) return $this;
rlm@3 154
rlm@3 155 if(!$y) $y = $ratio ? $this->meta['height']*$x/$this->meta['width'] : $this->meta['height'];
rlm@3 156 if(!$x) $x = $ratio ? $this->meta['width']*$y/$this->meta['height'] : $this->meta['width'];
rlm@3 157
rlm@3 158 $new = $this->create($x, $y);
rlm@3 159 imagecopyresampled($new, $this->image, 0, 0, 0, 0, $x, $y, $this->meta['width'], $this->meta['height']);
rlm@3 160 $this->set($new);
rlm@3 161
rlm@3 162 return $this;
rlm@3 163 }
rlm@3 164
rlm@3 165 /**
rlm@3 166 * Crops the image. The values are given like margin/padding values in css
rlm@3 167 *
rlm@3 168 * <b>Example</b>
rlm@3 169 * <ul>
rlm@3 170 * <li>crop(10) - Crops by 10px on all sides</li>
rlm@3 171 * <li>crop(10, 5) - Crops by 10px on top and bottom and by 5px on left and right sides</li>
rlm@3 172 * <li>crop(10, 5, 5) - Crops by 10px on top and by 5px on left, right and bottom sides</li>
rlm@3 173 * <li>crop(10, 5, 3, 2) - Crops by 10px on top, 5px by right, 3px by bottom and 2px by left sides</li>
rlm@3 174 * </ul>
rlm@3 175 *
rlm@3 176 * @param int $top
rlm@3 177 * @param int $right
rlm@3 178 * @param int $bottom
rlm@3 179 * @param int $left
rlm@3 180 * @return Image
rlm@3 181 */
rlm@3 182 public function crop($top, $right = null, $bottom = null, $left = null){
rlm@3 183 if(empty($this->image)) return $this;
rlm@3 184
rlm@3 185 if(!is_numeric($right) && !is_numeric($bottom) && !is_numeric($left))
rlm@3 186 $right = $bottom = $left = $top;
rlm@3 187
rlm@3 188 if(!is_numeric($bottom) && !is_numeric($left)){
rlm@3 189 $bottom = $top;
rlm@3 190 $left = $right;
rlm@3 191 }
rlm@3 192
rlm@3 193 if(!is_numeric($left))
rlm@3 194 $left = $right;
rlm@3 195
rlm@3 196 $x = $this->meta['width']-$left-$right;
rlm@3 197 $y = $this->meta['height']-$top-$bottom;
rlm@3 198
rlm@3 199 if($x<0 || $y<0) return $this;
rlm@3 200
rlm@3 201 $new = $this->create($x, $y);
rlm@3 202 imagecopy($new, $this->image, 0, 0, $left, $top, $x, $y);
rlm@3 203 $this->set($new);
rlm@3 204
rlm@3 205 return $this;
rlm@3 206 }
rlm@3 207
rlm@3 208 /**
rlm@3 209 * Flips the image horizontally or vertically. To Flip both just use ->rotate(180)
rlm@3 210 *
rlm@3 211 * @see Image::rotate()
rlm@3 212 * @param string $type Either horizontal or vertical
rlm@3 213 * @return Image
rlm@3 214 */
rlm@3 215 public function flip($type){
rlm@3 216 if(empty($this->image) || !in_array($type, array('horizontal', 'vertical'))) return $this;
rlm@3 217
rlm@3 218 $new = $this->create();
rlm@3 219
rlm@3 220 if($type=='horizontal')
rlm@3 221 for($x=0;$x<$this->meta['width'];$x++)
rlm@3 222 imagecopy($new, $this->image, $this->meta['width']-$x-1, 0, $x, 0, 1, $this->meta['height']);
rlm@3 223 elseif($type=='vertical')
rlm@3 224 for($y=0;$y<$this->meta['height'];$y++)
rlm@3 225 imagecopy($new, $this->image, 0, $this->meta['height']-$y-1, 0, $y, $this->meta['width'], 1);
rlm@3 226
rlm@3 227 $this->set($new);
rlm@3 228
rlm@3 229 return $this;
rlm@3 230 }
rlm@3 231
rlm@3 232 /**
rlm@3 233 * Stores the image in the desired directory or outputs it
rlm@3 234 *
rlm@3 235 * @param string $ext
rlm@3 236 * @param string $file
rlm@3 237 */
rlm@3 238 private function process($ext = null, $file = null){
rlm@3 239 if(!$ext) $ext = $this->meta['ext'];
rlm@3 240
rlm@3 241 if($ext=='png') imagesavealpha($this->image, true);
rlm@3 242 $fn = 'image'.$ext;
rlm@3 243 $fn($this->image, $file);
rlm@3 244
rlm@3 245 // If there is a new filename change the internal name too
rlm@3 246 if($file) $this->file = $file;
rlm@3 247 }
rlm@3 248
rlm@3 249 /**
rlm@3 250 * Saves the image to the given path
rlm@3 251 *
rlm@3 252 * @param string $file Leave empty to replace the original file
rlm@3 253 * @return Image
rlm@3 254 */
rlm@3 255 public function save($file = null){
rlm@3 256 if(empty($this->image)) return $this;
rlm@3 257
rlm@3 258 if(!$file) $file = $this->file;
rlm@3 259
rlm@3 260 $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
rlm@3 261 if(!$ext){
rlm@3 262 $file .= '.'.$this->meta['ext'];
rlm@3 263 $ext = $this->meta['ext'];
rlm@3 264 }
rlm@3 265
rlm@3 266 if($ext=='jpg') $ext = 'jpeg';
rlm@3 267
rlm@3 268 if(!in_array($ext, array('png', 'jpeg', 'gif')))
rlm@3 269 return $this;
rlm@3 270
rlm@3 271 $this->process($ext, $file);
rlm@3 272
rlm@3 273 return $this;
rlm@3 274 }
rlm@3 275
rlm@3 276 /**
rlm@3 277 * Outputs the manipulated image
rlm@3 278 *
rlm@3 279 * @return Image
rlm@3 280 */
rlm@3 281 public function show(){
rlm@3 282 if(empty($this->image)) return $this;
rlm@3 283
rlm@3 284 header('Content-type: '.$this->meta['mime']);
rlm@3 285 $this->process();
rlm@3 286
rlm@3 287 return $this;
rlm@3 288 }
rlm@3 289
rlm@3 290 }