PHP CLASS clsImage

1 : <?php
2 : /**************************************************************************
3 : * CLASS clsImage [PHP5] v1.0 09.12.2004
4 : *
5 : * http://www.zutz.nl/phpclasses
6 : *
7 : * this is an image manipulation class for PHP5 with the Zend engine
8 : * based on the GD Library. supported imagetypes: [ jpg | gif | png ]
9 : *
10 : * LICENSE
11 : * Public domain
12 : *
13 : * MODERATOR
14 :
15 : **************************************************************************/
16 :
17 :
18 :
19 : class clsImage implements interfaceImage {
20 : /* constants */
21 : const IMAGEDIRSEPARATOR = IMAGEDIRSEPARATOR;
22 : const IMAGEBASEURL = IMAGEBASEURL;
23 : const IMAGEBASEPATH = IMAGEBASEPATH;
24 : const IMAGEFONTDIR = IMAGEFONTDIR;
25 : const IMAGEINTERLACE = IMAGEINTERLACE;
26 : const IMAGEJPEGQUALITY = IMAGEJPEGQUALITY;
27 : const IMAGEDEBUG = IMAGEDEBUG;
28 :
29 : /* properties */
30 : private $ImageStream;
31 : private $aProperties;
32 : protected $sFileLocation;
33 : protected $sImageURL;
34 :
35 : public $interlace;
36 : public $jpegquality;
37 :
38 :
39 :
40 :
41 :
42 : /* default methods */
43 : function __construct() {
44 : /* constructor */
45 : $this->aProperties = array();
46 : $this->jpegquality = clsImage::IMAGEJPEGQUALITY;
47 :
48 : /* set interlace boolean */
49 : if (clsImage::IMAGEINTERLACE != 0) {
50 : $this->interlace = true;
51 : }
52 : else {
53 : $this->interlace = false;
54 : }
55 : }
56 :
57 : function __destruct() {
58 : /* destructor */
59 : unset($this->ImageStream);
60 : unset($this->aProperties);
61 : }
62 :
63 : public function __get($sPropertyName) {
64 : /* get properties */
65 : if (isset($this->aProperties[$sPropertyName])) {
66 : $sPropertyValue = $this->aProperties[$sPropertyName];
67 : }
68 : else {
69 : $sPropertyValue = NULL;
70 : }
71 :
72 : return($sPropertyValue);
73 : }
74 :
75 : private function __set($sPropertyName, $sPropertyValue) {
76 : /* set properties */
77 : if (!isset($this->aProperties)) {
78 : $this->aProperties = array();
79 : }
80 :
81 : $this->aProperties[$sPropertyName] = $sPropertyValue;
82 : }
83 :
84 : /* private methods */
85 : private function printError($sMessage, $sMethod = __METHOD__, $sLine = __LINE__) {
86 : /* echo errormessage to client and terminate script run */
87 : if(clsImage::IMAGEDEBUG == 1) {
88 : echo $sMethod . "(" . $sLine . ") " . $sMessage;
89 : }
90 :
91 : if(clsImage::IMAGEDEBUG == 2) {
92 : header("Location: class.image.debug.code.php?line={$sLine}#{$sLine}");
93 : }
94 :
95 : exit;
96 : }
97 :
98 : private function loadImage() {
99 : /* load a image from file */
100 : switch($this->type) {
101 : case 1:
102 : $this->ImageStream = @imagecreatefromgif($this->sFileLocation);
103 : break;
104 : case 2:
105 : $this->ImageStream = @imagecreatefromjpeg($this->sFileLocation);
106 : break;
107 : case 3:
108 : $this->ImageStream = @imagecreatefrompng($this->sFileLocation);
109 : break;
110 : default:
111 : $this->printError('invalid imagetype',__METHOD__,__LINE__);
112 : }
113 :
114 : if (!$this->ImageStream) {
115 : $this->printError('image not loaded',__METHOD__,__LINE__);
116 : }
117 : }
118 :
119 : private function saveImage() {
120 : /* store a memoryimage to file */
121 : if (!$this->ImageStream) {
122 : $this->printError('image not loaded',__METHOD__,__LINE__);
123 : }
124 :
125 : switch($this->type) {
126 : case 1:
127 : /* store a interlaced gif image */
128 : if ($this->interlace === true) {
129 : imageinterlace($this->ImageStream, 1);
130 : }
131 :
132 : imagegif($this->ImageStream,$this->sFileLocation);
133 : break;
134 : case 2:
135 : /* store a progressive jpeg image (with default quality value)*/
136 : if ($this->interlace === true) {
137 : imageinterlace($this->ImageStream, 1);
138 : }
139 :
140 : imagejpeg($this->ImageStream,$this->sFileLocation,$this->jpegquality);
141 : break;
142 : case 3:
143 : /* store a png image */
144 : imagepng($this->ImageStream,$this->sFileLocation);
145 : break;
146 : default:
147 : $this->printError('invalid imagetype',__METHOD__,__LINE__);
148 :
149 : if (!file_exists($this->sFileLocation)) {
150 : $this->printError('file not stored',__METHOD__,__LINE__);
151 : }
152 : }
153 : }
154 :
155 : private function showImage() {
156 : /* show a memoryimage to screen */
157 : if (!$this->ImageStream) {
158 : $this->printError('image not loaded',__METHOD__,__LINE__);
159 : }
160 :
161 : switch($this->type) {
162 : case 1:
163 : imagegif($this->ImageStream);
164 : break;
165 : case 2:
166 : imagejpeg($this->ImageStream);
167 : break;
168 : case 3:
169 : imagepng($this->ImageStream);
170 : break;
171 : default:
172 : $this->printError('invalid imagetype',__METHOD__,__LINE__);
173 : }
174 : }
175 :
176 : private function setFilenameExtension() {
177 : /* set the imahe type and mimetype */
178 : $sOldFilenameExtension = substr($this->filename,strlen($this->filename) - 4, 4);
179 : if ((strtolower($sOldFilenameExtension) != '.gif') &&
180 : (strtolower($sOldFilenameExtension) != '.jpg') &&
181 : (strtolower($sOldFilenameExtension) != '.jpeg') &&
182 : (strtolower($sOldFilenameExtension) != 'gif') &&
183 : (strtolower($sOldFilenameExtension) != 'jpg') &&
184 : (strtolower($sOldFilenameExtension) != 'jpeg') &&
185 : (strtolower($sOldFilenameExtension) != '.png')) {
186 : $this->printError('invalid filename extension '.$sOldFilenameExtension,__METHOD__,__LINE__);
187 : }
188 :
189 : switch($this->type) {
190 : case 1:
191 : $this->filename = substr($this->filename,0,strlen($this->filename) - 4) . '.gif';
192 : break;
193 : case 2:
194 : $this->filename = substr($this->filename,0,strlen($this->filename) - 4) . '.jpg';
195 : break;
196 : case 3:
197 : $this->filename = substr($this->filename,0,strlen($this->filename) - 4) . '.png';
198 : break;
199 : default:
200 : $this->printError('invalid imagetype',__METHOD__,__LINE__);
201 : }
202 : }
203 :
204 : private function setImageType($iType) {
205 : /* set the imahe type and mimetype */
206 : switch($iType) {
207 : case 1:
208 : $this->type = $iType;
209 : $this->mimetype = 'image/gif';
210 : $this->setFilenameExtension();
211 : break;
212 : case 2:
213 : $this->type = $iType;
214 : $this->mimetype = 'image/jpeg';
215 : $this->setFilenameExtension();
216 : break;
217 : case 3:
218 : $this->type = $iType;
219 : $this->mimetype = 'image/png';
220 : $this->setFilenameExtension();
221 : break;
222 : default:
223 : $this->printError('invalid imagetype',__METHOD__,__LINE__);
224 : }
225 : }
226 :
227 : private function setLocations($sFileName) {
228 : /* set the photo url */
229 : $this->filename = $sFileName;
230 :
231 :
232 : $this->sFileLocation = clsImage::IMAGEBASEPATH.clsImage::IMAGEDIRSEPARATOR . $this->filename;
233 : $this->sImageURL = clsImage::IMAGEBASEURL . '/' . $this->filename;
234 :
235 : }
236 :
237 : private function initializeImageProperties() {
238 : /* get imagesize from file and set imagesize array */
239 : list($this->width, $this->height, $iType, $this->htmlattributes) = getimagesize($this->sFileLocation);
240 :
241 : if (($this->width < 1) || ($this->height < 1)) {
242 : $this->printError('invalid imagesize',__METHOD__,__LINE__);
243 : }
244 :
245 : $this->setImageOrientation();
246 : $this->setImageType($iType);
247 : }
248 :
249 : private function setImageOrientation() {
250 : /* get image-orientation based on imagesize
251 : options: [ portrait | landscape | square ] */
252 :
253 : if ($this->width < $this->height) {
254 : $this->orientation = 'portrait';
255 : }
256 :
257 : if ($this->width > $this->height) {
258 : $this->orientation = 'landscape';
259 : }
260 :
261 : if ($this->width == $this->height) {
262 : $this->orientation = 'square';
263 : }
264 : }
265 :
266 : /* public methods */
267 : public function loadfile($sFileName) {
268 : /* load an image from file into memory */
269 : $this->setLocations($sFileName);
270 :
271 :
272 :
273 :
274 :
275 : if (file_exists($this->sFileLocation)) {
276 : $this->initializeImageProperties();
277 : $this->loadImage();
278 : }
279 : else {
280 :
281 : $this->printError('file not found '.$this->sFileLocation,__METHOD__,__LINE__);
282 : }
283 :
284 : }
285 :
286 : public function savefile($sFileName = NULL) {
287 : /* store memory image to file */
288 : if ((isset($sFileName)) && ($sFileName != '')) {
289 : $this->setLocations($sFileName);
290 : }
291 :
292 : $this->saveImage();
293 : }
294 :
295 : public function preview() {
296 : /* print memory image to screen */
297 : header("Content-type: {$this->mimetype}");
298 : $this->showImage();
299 : }
300 :
301 : public function showhtml($sAltText = NULL, $sClassName = NULL) {
302 : /* print image as htmltag */
303 : if (file_exists($this->sFileLocation)) {
304 : /* set html alt attribute */
305 : if ((isset($sAltText)) && ($sAltText != '')) {
306 : $htmlAlt = " alt=\"".$sAltText."\"";
307 : }
308 : else {
309 : $htmlAlt = "";
310 : }
311 :
312 : /* set html class attribute */
313 : if ((isset($sClassName)) && ($sClassName != '')) {
314 : $htmlClass = " class=\"".$sClassName."\"";
315 : }
316 : else {
317 : $htmlClass = " border=\"0\"";
318 : }
319 :
320 : $sHTMLOutput = '<img src="'.$this->sImageURL.'"'.$htmlClass.' width="'.$this->width.'" height="'.$this->height.'"'.$htmlAlt.'>';
321 : print $sHTMLOutput;
322 : }
323 : else {
324 : $this->printError('afile not found',__METHOD__,__LINE__);
325 : }
326 : }
327 :
328 : public function resize($iNewWidth, $iNewHeight) {
329 : /* resize the memoryimage do not keep ratio */
330 : if (!$this->ImageStream) {
331 : $this->printError('image not loaded',__METHOD__,__LINE__);
332 : }
333 :
334 : if(function_exists("imagecopyresampled")){
335 : $ResizedImageStream = imagecreatetruecolor($iNewWidth, $iNewHeight);
336 : $blanc = imagecolorallocate($ResizedImageStream, 255, 255, 255);
337 : imagefill ($ResizedImageStream, 1 , 1 , $blanc);
338 : imagecopyresampled($ResizedImageStream, $this->ImageStream, 0, 0, 0, 0, $iNewWidth, $iNewHeight, $this->width, $this->height);
339 : }
340 : else{
341 : $ResizedImageStream = imagecreate($iNewWidth, $iNewHeight);
342 : $blanc = imagecolorallocate($ResizedImageStream, 255, 255, 255);
343 : imagefill ($ResizedImageStream, 1 , 1 , $blanc);
344 : imagecopyresized($ResizedImageStream, $this->ImageStream, 0, 0, 0, 0, $iNewWidth, $iNewHeight, $this->width, $this->height);
345 : }
346 :
347 : $this->ImageStream = $ResizedImageStream;
348 : $this->width = $iNewWidth;
349 : $this->height = $iNewHeight;
350 : $this->setImageOrientation();
351 : }
352 :
353 : public function resizetowidth($iNewWidth) {
354 : /* resize image to given width (keep ratio) */
355 : $iNewHeight = ($iNewWidth / $this->width) * $this->height;
356 : $this->resize($iNewWidth,$iNewHeight);
357 : }
358 :
359 : public function resizetoheight($iNewHeight) {
360 : /* resize image to given height (keep ratio) */
361 : $iNewWidth = ($iNewHeight / $this->height) * $this->width;
362 : $this->resize($iNewWidth,$iNewHeight);
363 : }
364 :
365 : public function resizetopercentage($iPercentage) {
366 : /* resize image to given percentage (keep ratio) */
367 : $iPercentageMultiplier = $iPercentage / 100;
368 : $iNewWidth = $this->width * $iPercentageMultiplier;
369 : $iNewHeight = $this->height * $iPercentageMultiplier;
370 :
371 : $this->resize($iNewWidth,$iNewHeight);
372 : }
373 :
374 : public function crop($iNewWidth, $iNewHeight, $iResize = 0) {
375 : /* crop image (first resize with keep ratio) */
376 : if (!$this->ImageStream) {
377 : $this->printError('image not loaded',__METHOD__,__LINE__);
378 : }
379 :
380 : /* resize imageobject in memory if resize percentage is set */
381 : if ($iResize > 0) {
382 : $this->resizetopercentage($iResize);
383 : }
384 :
385 : /* constrain width and height values */
386 : /* if (($iNewWidth > $this->width) || ($iNewWidth < 0)) {
387 : $this->printError('width out of range',__METHOD__,__LINE__);
388 : }
389 : if (($iNewHeight > $this->height) || ($iNewHeight < 0)) {
390 : $this->printError('height out of range',__METHOD__,__LINE__);
391 : }
392 : */
393 : /* create blank image with new sizes */
394 : $CroppedImageStream = ImageCreateTrueColor($iNewWidth,$iNewHeight);
395 : $blanc = imagecolorallocate($CroppedImageStream, 255, 255, 255);
396 : imagefill ($CroppedImageStream, 1 , 1 , $blanc);
397 :
398 : /* calculate size-ratio */
399 : $iWidthRatio = $this->width / $iNewWidth;
400 : $iHeightRatio = $this->height / $iNewHeight;
401 : $iHalfNewHeight = $iNewHeight / 2;
402 : $iHalfNewWidth = $iNewWidth / 2;
403 :
404 : /* if the image orientation is landscape */
405 : if($this->orientation == 'landscape') {
406 : /* calculate resize width parameters */
407 : $iResizeWidth = $this->width / $iHeightRatio;
408 : $iHalfWidth = $iResizeWidth / 2;
409 : $iDiffWidth = $iHalfWidth - $iHalfNewWidth;
410 :
411 : if(function_exists("imagecopyresampled")){
412 : imagecopyresampled($CroppedImageStream,$this->ImageStream,-$iDiffWidth,0,0,0,$iResizeWidth,$iNewHeight,$this->width,$this->height);
413 : }
414 : else {
415 : imagecopyresized($CroppedImageStream,$this->ImageStream,-$iDiffWidth,0,0,0,$iResizeWidth,$iNewHeight,$this->width,$this->height);
416 : }
417 : }
418 : /* if the image orientation is portrait or square */
419 : elseif(($this->orientation == 'portrait') || ($this->orientation == 'square')) {
420 : /* calculate resize height parameters */
421 : $iResizeHeight = $this->height / $iWidthRatio;
422 : $iHalfHeight = $iResizeHeight / 2;
423 : $iDiffHeight = $iHalfHeight - $iHalfNewHeight;
424 :
425 : if(function_exists("imagecopyresampled")){
426 : imagecopyresampled($CroppedImageStream,$this->ImageStream,0,-$iDiffHeight,0,0,$iNewWidth,$iResizeHeight,$this->width,$this->height);
427 : }
428 : else {
429 : imagecopyresized($CroppedImageStream,$this->ImageStream,0,-$iDiffHeight,0,0,$iNewWidth,$iResizeHeight,$this->width,$this->height);
430 : }
431 : }
432 : else {
433 : if(function_exists("imagecopyresampled")){
434 : imagecopyresampled($CroppedImageStream,$this->ImageStream,0,0,0,0,$iNewWidth,$iNewHeight,$this->width,$this->height);
435 : }
436 : else {
437 : imagecopyresized($CroppedImageStream,$this->ImageStream,0,0,0,0,$iNewWidth,$iNewHeight,$this->width,$this->height);
438 : }
439 : }
440 :
441 : $this->ImageStream = $CroppedImageStream;
442 : $this->width = $iNewWidth;
443 : $this->height = $iNewHeight;
444 : $this->setImageOrientation();
445 : }
446 :
447 : public function writetext($sText, $iFontSize = 10, $sTextColor = '0,0,0', $sFontFilename = 'arial', $iXPos = 5, $iYPos = 15, $iTextAngle = 0) {
448 : /* write text on image */
449 : if (!$this->ImageStream) {
450 : $this->printError('image not loaded',__METHOD__,__LINE__);
451 : }
452 :
453 : if (($iXPos > $this->width) || ($iXPos < 0)) {
454 : $this->printError('x-pos out of range',__METHOD__,__LINE__);
455 : }
456 :
457 : if (($iYPos > $this->height) || ($iYPos < 0)) {
458 : $this->printError('y-pos out of range',__METHOD__,__LINE__);
459 : }
460 :
461 : $sFont = clsImage::IMAGEFONTDIR . clsImage::IMAGEDIRSEPARATOR . $sFontFilename;
462 : $aTextColor = explode(',',$sTextColor,3);
463 : $ImageColor = imagecolorallocate($this->ImageStream,$aTextColor[0],$aTextColor[1],$aTextColor[2]);
464 : $iLineWidth = imagettfbbox($iFontSize, $iTextAngle, $sFont, $sText);
465 : imagettftext($this->ImageStream, $iFontSize, $iTextAngle, $iXPos, $iYPos, $ImageColor, $sFont, $sText);
466 : }
467 :
468 : public function convert($sTargetType) {
469 : /* convert image to given type [ jpg | gif | png ] */
470 : if (!$this->ImageStream) {
471 : $this->printError('image not loaded',__METHOD__,__LINE__);
472 : }
473 :
474 : switch($sTargetType) {
475 : case 'gif':
476 : $this->setImageType(1);
477 : break;
478 : case 'jpg':
479 : $this->setImageType(2);
480 : break;
481 : case 'png':
482 : $this->setImageType(3);
483 : break;
484 : default: $this->printError('invalid imagetype',__METHOD__,__LINE__);
485 : }
486 : }
487 : }
488 : ?>