Image Manipulator (v0.5)

Item 4 of 9

» Download this file

1   <?php
2   
3   
4   /**
5    * Class: ImageManipulator
6    *
7    * Provides a small library of image manipulation functions using the inbuilt PHP/GD2 functions.
8    *
9    * @author Dan Pupius <www.pupius.co.uk>
10   * @version 0.5
11   * @copyright ©2003 Dan Pupius
12   * @package Utility
13   * @subpackage Classes
14   */
15  
16  class ImageManipulator {
17  
18  	/**
19  	 * @var string Location of current image
20  	 */
21  	var $curfile = "";
22  
23  	/**
24  	 * @var string Filename of current image
25  	 */
26  	var $filename = "";
27  
28  	/**
29  	 * @var string Extension of current image
30  	 */
31  	var $ext = "";
32  
33  	/**
34  	 * @var mixed Resource holder for an image that is loaded into the object
35  	 */
36  	var $im = null;
37  
38  	/**
39  	 * @var int Number between 0 and 100 representing output quality of image
40  	 */
41  	var $quality = 80;
42  
43  	/**
44  	 * @var mixed RGB array representing the background colour used in fills
45  	 */
46  	var $bgcolor = array(0,0,0);
47  
48  	/**
49  	 * @var mixed RGB array representing the foreground colour used in borders and text
50  	 */
51  	var $color = array(200,200,200);
52  
53  	/**
54  	 * @var mixed Array of weights used when making an image grey scale.  Preferably add to 3 to keep same overall gamma.
55  	 */
56  	var $gamma = array(1,1,1);	//Represent RGB values.
57  
58  
59  
60  	/**
61  	 * Constructor function - if optional filename is sent then it will auto load the imaeg into the object
62  	 *
63  	 * @param string $img image path or url
64  	 * @return boolean Whether image was successfully loaded
65  	 * @access public
66  	 */
67  	function ImageManipulator($img="") {
68  		if($img!="") return $this->load_image($img);
69  	}
70  
71  
72  
73  	/**
74  	 * Loads an image file into the class
75  	 *
76  	 * @param string $img image path or url
77  	 * @return boolean Whether image was successfully loaded
78  	 * @access public
79  	 */
80  	function load_image($img) {
81  		if(!file_exists($img) || !is_file($img)) return false;
82  		$fileinfo = pathinfo($img);
83  
84  		$this->filename = $fileinfo["basename"];
85  		$this->ext = strtolower($fileinfo["extension"]);
86  
87  		//depending on the image type create
88  		switch($this->ext) {
89  			case "gif": $im = @imagecreatefromgif($img); break;
90  			case "jpg": $im = @imagecreatefromjpeg($img); break;
91  			case "png": $im = @imagecreatefrompng($img); break;
92  			default: return false;
93  		}
94  		if(!$im) return false;
95  		else $this->im = $im;
96  
97  		return true;
98  	}
99  
100 	/**
101 	 * Destroys the image held in memory - always call this before the end of your script
102 	 *
103 	 * @access public
104 	 */
105 	function end() {
106 		if(!$this->im) return false;
107 		imagedestroy($this->im);
108 	}
109 
110 
111 	/**
112 	 * Resamples the current image to a specified size.  This function does not take into accound aspect-ratio.
113 	 *
114 	 * @param integer $w Width of new image
115 	 * @param integer $h Height of new image
116 	 * @return boolean Whether resize was sucessful
117 	 * @access public
118 	 */
119 	function resample($w,$h) {
120 		if(!$this->im) return false;
121 
122 		//create a destination image
123 		$dest = imagecreatetruecolor($w,$h);
124 
125 		//try and resample
126 		$r = imagecopyresampled($dest,$this->im,0,0,0,0,$w,$h,imagesx($this->im),imagesy($this->im));
127 
128 		//resample was successful so replace original image with new one
129 		if($r) {
130 			imagedestroy($this->im);
131 			$this->im = imagecreatetruecolor($w,$h);
132 			imagecopy($this->im,$dest,0,0,0,0,$w,$h);
133 			imagedestroy($dest);
134 			return true;
135 		}
136 		
137 		//resample failed
138 		else return false;
139 	}
140 
141 
142 	/**
143 	 * Uses resample to resize an image so that it fits inside a certain box while maintaining aspect
144 	 * ratio.  If "clip "is true then it will resize to the smallest dimension and clip the remaining region.
145 	 * If "clip" is false (default) then it will center the image inside the box, and paint a background
146 	 * colour in the remaining area.
147 	 *
148 	 * @param integer $w Width of new image
149 	 * @param integer $h Height of new image
150 	 * @param boolean $noclip Whether to fill entire box or *clip* areas that overflow
151 	 * @param boolean $noenlarge If true then the file won't be enlarged to fit the spaec but rather sit in the middle
152 	 * @return boolean Whether it was sucessful
153 	 * @access public
154 	 */
155 	function resize_to_fit($w,$h,$noclip=true,$noenlarge=false) {
156 		if(!$this->im) return false;
157 
158 		$curw = imagesx($this->im);
159 		$curh = imagesy($this->im);
160 		
161 		//create a destination image
162 		$dest = imagecreatetruecolor($w,$h);
163 		
164 		//set background colour
165 		$bg = ImageColorAllocate($dest,$this->bgcolor[0],$this->bgcolor[1],$this->bgcolor[2]);
166  		ImageFilledRectangle ($dest, 0, 0, $w, $h, $bg);
167 		
168 		//if in clip mode then fit to shortest side, otherwise fit to longest
169 		if( ($noclip && $curw/$w>=$curh/$h) || (!$noclip && $curw/$w < $curh/$h) ) {
170 			$newh = $curh / ($curw/$w);
171 			$neww = $w;
172 		} else {
173 			$neww = $curw / ($curh/$h);
174 			$newh = $h;
175 		}
176 
177 		//try and resample by resized region to middle of the image
178 		if($curw<$w && $curh<$h && $noenlarge) $r = imagecopyresampled($dest,$this->im, ($w/2)-($curw/2), ($h/2)-($curh/2), 0, 0, $curw, $curh, $curw, $curh); //no resize just copy into middle of canvas
179 		else $r = imagecopyresampled($dest,$this->im, ($w/2)-($neww/2), ($h/2)-($newh/2), 0, 0, $neww, $newh, $curw, $curh); //resize, up or down
180 		
181 		//finish up if it worked
182 		if($r) {
183 			imagedestroy($this->im);
184 			$this->im = imagecreatetruecolor($w,$h);
185 			imagecopy($this->im,$dest,0,0,0,0,$w,$h);
186 			imagedestroy($dest);
187 			return true;
188 		}
189 
190 		//resample failed
191 		else return false;
192 
193 	}
194 
195 	/**
196 	 * Sets a specific RGB colour as transparent (only works when outputing as a PNG or GIF)
197 	 *
198 	 * @param integer $r Red value
199 	 * @param integer $g Green value
200 	 * @param integer $b Blue value
201 	 * @return boolean Whether it was sucessful
202 	 * @access public
203 	 */
204 	function set_transparency($r=0,$g=0,$b=0) {
205 		if(!$this->im) return false;
206 
207 		//find the index of the colour to make transparent, if it doesn't exist then exit.
208 		$index = imagecolorexact($this->im,$r,$g,$b);
209 		if($index==-1) return false;
210 
211 		//set the transparency
212 		imagecolortransparent($this->im,$index);
213 
214 		return true;
215 	}
216 
217 
218 
219 	/**
220 	 * Desaturates an image, id optional $shade variable = 0 then image will be grey scale, 1 = red, 2 = greem 3 = blue
221 	 *
222 	 * NOTE: By adjusting the weight array prior to desaturating the image you can split the channels of an image.
223 	 *
224 	 * @param integer $shade What colour to shade the image
225 	 * @return boolean Whether it was sucessful
226 	 * @access public
227 	 */
228 	function desaturate($shade=0){
229 		if(!$this->im) return false;
230 
231 		//convert o,age to 256 colours
232 		ImageTrueColorToPalette($this->im,1,256);
233 
234 		//calculate total number of colours in palette
235 		$total = ImageColorsTotal($this->im);
236 
237 		//for each colour make it grey
238 		for($i=0;$i<$total;$i++){
239 			$old = ImageColorsForIndex($this->im,$i);
240 
241 			//get correct colouring by performing a weighted average of the 3
242 			$grey = round(($this->gamma[0]*$old["red"] + $this->gamma[1]*$old["green"] + $this->gamma[2]*$old["blue"]) / 3);
243 
244 			if($shade==1)      ImageColorSet($this->im,$i,$grey,0,0);
245 			else if($shade==2) ImageColorSet($this->im,$i,0,$grey,0);
246 			else if($shade==3) ImageColorSet($this->im,$i,0,0,$grey);
247 			else               ImageColorSet($this->im,$i,$grey,$grey,$grey);
248 		}
249 
250 		return true;
251 	}
252 
253 	/**
254 	 * Converts an image to n-colours
255 	 *
256 	 * @param integer $colors Number of colours in pallete
257 	 * @return boolean Whether it was sucessful
258 	 * @access public
259 	 */
260 	function reduce_colors($colors=255) {
261 		//convert o,age to 256 colours
262 		if(!function_exists("ImageTrueColorToPalette")) return false;
263 		ImageTrueColorToPalette($this->im,1,$colors);
264 		return true;
265 	}
266 
267 	/**
268 	 * Draws a border round the edge of the image using the $color variable storred in the object
269 	 *
270 	 * @param integer $size Border size in pixels
271 	 * @return boolean Whether it was sucessful
272 	 * @access public
273 	 */
274 	function draw_border($size) {
275 		if(!$this->im) return false;
276 
277 		//rectangle works out 1px bigger than you'd expect so...
278 		$size = $size-1;
279 
280 		//get image size
281 		$w = imagesx($this->im);
282 		$h = imagesy($this->im);
283 	
284 		//get the border colour
285 		$c = imagecolorallocate($this->im,$this->color[0],$this->color[1],$this->color[2]);
286 		
287 		//draw lines
288 		ImageFilledRectangle($this->im,0,0,$w,$size,$c);	//top border
289 		ImageFilledRectangle($this->im,0,$h-$size-1,$w,$h,$c);	//bottom border
290 		ImageFilledRectangle($this->im,0,0,$size,$h,$c);		//left border
291 		ImageFilledRectangle($this->im,$w-$size-1,0,$w,$h,$c);	//right border
292 	
293 		return true;
294 	}
295 
296 
297 	/**
298 	 * sends the image currently storred within this object as a jpeg to the output buffer (headers included)
299 	 *
300 	 * @return boolean Whether ouput was sucessful
301 	 * @access public
302 	 */
303 	function output_jpeg() {
304 		if(!$this->im || !function_exists("imagejpeg")) return false;
305 		header('Content-Type: image/jpeg');
306 		header("Content-Disposition: inline; filename={$this->filename}.jpg");	//neat header to tell the browser what the filename should be
307 		imagejpeg($this->im,"",$this->quality);
308 		return true;
309 	}
310 
311 	/**
312 	 * sends the image currently storred within this object as a png to the output buffer (headers included)
313 	 *
314 	 * @return boolean Whether ouput was sucessful
315 	 * @access public
316 	 */
317 	function output_png() {
318 		if(!$this->im || !function_exists("imagepng")) return false;
319 		header('Content-Type: image/jpeg');
320 		header("Content-Disposition: inline; filename={$this->filename}.png");
321 		imagepng($this->im);
322 		return true;
323 	}
324 	
325 	/**
326 	 * Saves the image currently storred within this object as a jpeg on the local file system
327 	 *
328 	 * @return boolean Whether save was sucessful
329 	 * @access public
330 	 */
331 	function save_jpeg($filename) {
332 		if(!$this->im || !function_exists("imagejpeg")) return false;
333 		imagejpeg($this->im,$filename,$this->quality);
334 		return true;
335 	}
336 
337 	/**
338 	 * Saves the image currently storred within this object as a png on the local file system
339 	 *
340 	 * @return boolean Whether sav was sucessful
341 	 * @access public
342 	 */
343 	function save_png($filename) {
344 		if(!$this->im || !function_exists("imagepng")) return false;
345 		imagepng($this->im,$filename);
346 		return true;
347 	}
348 }
349 
350 //DEMO:
351 /*
352 $i = new ImageManipulator("balls.jpg");
353 $i->resize_to_fit(640,480,false,true);	//resize image to 640x480, but make sure image isn't clipped and if it's smaller than 640x480 just increase the canvas
354 $i->color = array(255,255,255);		//set foreground colour to white
355 $i->draw_border(15);			//draw a 15px border
356 $i->color = array(0,0,0);		//set foreground to black
357 $i->draw_border(1);			//draw 1px border
358 $i->output_jpeg();			//output image as jpeg
359 $i->end();				//ensure memory is freed up
360 */
361 
362 ?>
363 

Back to top