CWIS Developer Documentation
Axis--Image.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # Axis--Image.php
4 # A PHP Object to Support Image File Manipulation
5 #
6 # Copyright 1999-2013 Axis Data
7 # This code is free software that can be used or redistributed under the
8 # terms of Version 2 of the GNU General Public License, as published by the
9 # Free Software Foundation (http://www.fsf.org).
10 #
11 # Part of the AxisPHP library v1.2.5
12 # For more information see http://www.axisdata.com/AxisPHP/
13 #
14 
15 class Image {
16 
17  # ---- PUBLIC INTERFACE --------------------------------------------------
18 
20  {
21  # set debug level
22  $this->DebugLevel = $DebugLevel;
23 
24  # save source file name
25  $this->SourceFileName = $SourceFileName;
26 
27  # set default values
28  $this->JpegSaveQuality = 80;
29  $this->ErrorStatus = AI_OKAY;
30  $this->FailedCommand = "";
31 
32  # get GD library version
33  if (extension_loaded("gd"))
34  {
35  if (in_array("imagecreatetruecolor", get_extension_funcs("gd")))
36  {
37  $this->GDVersion = 2;
38  }
39  else
40  {
41  $this->GDVersion = 1;
42  }
43  }
44  else
45  {
46  $this->GDVersion = 0;
47  }
48 
49  # if source file is readable
50  if (is_readable(realpath($SourceFileName)))
51  {
52  # if support is available for this image type
53  if ($this->ImageFormatSupportedByPhp())
54  {
55  # create PHP image object
56  switch ($this->Type())
57  {
58  case IMGTYPE_JPEG:
59  if ($this->DebugLevel > 1) { print("AI: file format is JPEG<br>\n"); }
60  $this->ImageObj = imagecreatefromjpeg($this->SourceFileName);
61  break;
62 
63  case IMGTYPE_GIF:
64  if ($this->DebugLevel > 1) { print("AI: file format is GIF<br>\n"); }
65  $this->ImageObj = imagecreatefromgif($this->SourceFileName);
66  break;
67 
68  case IMGTYPE_BMP:
69  if ($this->DebugLevel > 1) { print("AI: file format is BMP<br>\n"); }
70  $this->ImageObj = imagecreatefrombmp($this->SourceFileName);
71  break;
72 
73  case IMGTYPE_PNG:
74  if ($this->DebugLevel > 1) { print("AI: file format is PNG<br>\n"); }
75  $this->ImageObj = imagecreatefrompng($this->SourceFileName);
76  break;
77 
78  default:
79  $this->ErrorStatus = AI_INTERNALERROR;
80  break;
81  }
82 
83  # if PHP image object creation failed
84  if (FALSE === $this->ImageObj)
85  {
86  # set error status
87  $this->ErrorStatus = AI_IMGOBJCREATEFAILED;
88  }
89  }
90  else
91  {
92  # set error status to indicate unsupported image format
93  $this->ErrorStatus = AI_UNSUPPORTEDFORMAT;
94  }
95  }
96  else
97  {
98  # set error status
99  $this->ErrorStatus = AI_FILEUNREADABLE;
100  }
101  }
102 
103  # save image with a new name and (optionally) a new type
104  function SaveAs($FileName, $NewImageType = NULL)
105  {
106  # assume we will succeed
107  $this->ErrorStatus = AI_OKAY;
108 
109  # if destination file exists and is not writable
110  if (file_exists($FileName) && (is_writable($FileName) != TRUE))
111  {
112  # set error code
113  $this->ErrorStatus = AI_DESTINATIONUNWRITABLE;
114  }
115  # else if destination directory is not writable
116  elseif (is_writable(dirname($FileName)) != TRUE)
117  {
118  # set error code
119  $this->ErrorStatus = AI_DESTINATIONUNWRITABLE;
120  }
121  else
122  {
123  # if no image type specified try to determine based on file name or use source file type
124  if ($NewImageType == NULL)
125  {
126  if ($this->Type($FileName) != IMGTYPE_UNKNOWN)
127  { $NewImageType = $this->Type($FileName); }
128  else
129  { $NewImageType = $this->Type(); }
130  }
131 
132  # if input and output types both supported
133  if ($this->ImageFormatSupportedByPhp() && $this->ImageFormatSupportedByPhp($NewImageType))
134  {
135  # if image cropping or scaling was requested
136  if (isset($this->CroppedXSize)
137  || isset($this->ScaledXSize)
138  || isset($this->ScaledYSize))
139  {
140  # determine destination image size
141  if (isset($this->ScaledXSize) && isset($this->ScaledYSize)
142  && ($this->MaintainAspectRatio != TRUE))
143  {
144  $DstXSize = $this->ScaledXSize;
145  $DstYSize = $this->ScaledYSize;
146  }
147  elseif (isset($this->ScaledXSize)
148  || ($this->ScaledXSize > $this->ScaledYSize))
149  {
150  $DstXSize = $this->ScaledXSize;
151  $DstYSize = ($this->ScaledXSize * $this->YSize())
152  / $this->XSize();
153  }
154  elseif (isset($this->ScaledYSize))
155  {
156  $DstXSize = ($this->ScaledYSize * $this->XSize())
157  / $this->YSize();
158  $DstYSize = $this->ScaledYSize;
159  }
160  elseif (isset($this->CroppedXSize))
161  {
162  $DstXSize = $this->CroppedXSize;
163  $DstYSize = $this->CroppedYSize;
164  }
165  else
166  {
167  $DstXSize = $this->XSize();
168  $DstYSize = $this->YSize();
169  }
170 
171  # create destination image object
172  if (($NewImageType == IMGTYPE_GIF) || ($this->GDVersion < 2))
173  {
174  $DstImage = imagecreate($DstXSize, $DstYSize);
175  }
176  else
177  {
178  $DstImage = imagecreatetruecolor($DstXSize, $DstYSize);
179  }
180 
181  # determine area of source image to use
182  if (isset($this->CroppedXSize))
183  {
184  $SrcXSize = $this->CroppedXSize;
185  $SrcYSize = $this->CroppedYSize;
186  }
187  else
188  {
189  $SrcXSize = $this->XSize();
190  $SrcYSize = $this->YSize();
191  }
192 
193  # copy/scale portion of original image to destination image
194  if ($this->GDVersion >= 2)
195  {
196  imagecopyresampled($DstImage, $this->ImageObj,
197  0, 0,
198  $this->CroppedXOrigin, $this->CroppedYOrigin,
199  $DstXSize, $DstYSize,
200  $SrcXSize, $SrcYSize);
201  }
202  else
203  {
204  imagecopyresized($DstImage, $this->ImageObj,
205  0, 0,
206  $this->CroppedXOrigin, $this->CroppedYOrigin,
207  $DstXSize, $DstYSize,
208  $SrcXSize, $SrcYSize);
209  }
210  }
211  else
212  {
213  $DstImage =& $this->ImageObj;
214  }
215 
216  # save image to new file
217  switch ($NewImageType)
218  {
219  case IMGTYPE_GIF:
220  imagegif($DstImage, $FileName);
221  break;
222 
223  case IMGTYPE_JPEG:
224  imagejpeg($DstImage, $FileName, $this->JpegSaveQuality);
225  break;
226 
227  case IMGTYPE_PNG:
228  imagepng($DstImage, $FileName);
229  break;
230 
231  case IMGTYPE_BMP:
232  imagewbmp($DstImage, $FileName);
233 
234  default:
235  $this->ErrorStatus = AI_INTERNALERROR;
236  break;
237  }
238  }
239  else
240  {
241  # set error status to indicate unsupported image format
242  $this->ErrorStatus = AI_UNSUPPORTEDFORMAT;
243  }
244  }
245 
246  # report success or failure to caller
247  return $this->ErrorStatus;
248  }
249 
250  # return the X (horizontal) image size in pixels
251  function XSize()
252  {
253  $this->ReadSize();
254  return $this->ImageXSize;
255  }
256 
257  # return the Y (vertical) image size in pixels
258  function YSize()
259  {
260  $this->ReadSize();
261  return $this->ImageYSize;
262  }
263 
264  # specify the size to scale the image to for the next SaveAs()
266  {
267  # save size for scaling
268  $this->ScaledXSize = $ScaledXSize;
269  $this->ScaledYSize = $ScaledYSize;
270  $this->MaintainAspectRatio = $MaintainAspectRatio;
271  }
272 
273  # specify the size to crop the image to for the next SaveAs()
275  {
276  # save origin and size for cropping
277  $this->CroppedXSize = $CroppedXSize;
278  $this->CroppedYSize = $CroppedYSize;
279  $this->CroppedXOrigin = $CroppedXOrigin;
280  $this->CroppedYOrigin = $CroppedYOrigin;
281  }
282 
283  # return the image type
284  function Type($FileName = NULL)
285  {
286  if ($FileName == NULL) { $FileName = $this->SourceFileName; }
287  if (preg_match("/.*\\.jp[e]{0,1}g$/i", $FileName)) { return IMGTYPE_JPEG; }
288  elseif (preg_match("/.*\\.gif$/i", $FileName)) { return IMGTYPE_GIF; }
289  elseif (preg_match("/.*\\.bmp$/i", $FileName)) { return IMGTYPE_BMP; }
290  elseif (preg_match("/.*\\.png$/i", $FileName)) { return IMGTYPE_PNG; }
291  else { return IMGTYPE_UNKNOWN; }
292  }
293 
298  public function Mimetype()
299  {
300  switch ($this->Type())
301  {
302  # if the image type is known
303  case IMGTYPE_JPEG: return "image/jpeg";
304  case IMGTYPE_PNG: return "image/png";
305  case IMGTYPE_GIF: return "image/gif";
306  case IMGTYPE_BMP: return "image/bmp";
307 
308  # the image type isn't known
309  default:
310  $Mimetype = NULL;
311  $FilePath = $this->SourceFileName;
312 
313  # PHP >= 5.3
314  if (function_exists("finfo_open"))
315  {
316  # construct a handle to get mimetype info
317  $FInfoHandle = finfo_open(FILEINFO_MIME);
318 
319  # if the handle is okay
320  if ($FInfoHandle)
321  {
322  # get the mimetype info for the file
323  $FInfoMime = finfo_file($FInfoHandle, $FilePath);
324 
325  # close the handle
326  finfo_close($FInfoHandle);
327 
328  # if the mimetype info fetch was successful
329  if ($FInfoMime)
330  {
331  $Mimetype = $FInfoMime;
332  }
333  }
334  }
335 
336  # PHP < 5.3
337  else if (function_exists("mime_content_type"))
338  {
339  # mime_content_type has been deprecated, but it may be
340  # the only way to get the mimetype for PHP < 5.3
341  $MimeType = mime_content_type($FilePath);
342 
343  # if the mimetype info fetch was successful
344  if ($MimeType)
345  {
346  $Mimetype = $MimeType;
347  }
348  }
349 
350  return $Mimetype;
351  }
352  }
353 
354  # return the file name extension for the image
355  static function Extension($Type = NULL)
356  {
357  if ($Type === NULL)
358  {
359  return Image::$AxisImageFileExtensions[$this->Type()];
360  }
361  else
362  {
363  if (isset(Image::$AxisImageFileExtensions[$Type]))
364  {
365  return Image::$AxisImageFileExtensions[$Type];
366  }
367  else
368  {
369  return NULL;
370  }
371  }
372  }
373 
374  # set/get the quality (0-100) for JPEG images created with SaveAs()
375  function JpegQuality($NewSetting = NULL)
376  {
377  if ($NewSetting != NULL) { $this->JpegSaveQuality = $NewSetting; }
378  return $this->JpegSaveQuality;
379  }
380 
381  # return supported image formats
382  static function SupportedFormats()
383  {
384  # start out assuming no formats are supported
385  $Supported = 0;
386 
387  # if JPEG is supported by PHP
388  if (function_exists("imagetypes") && defined("IMG_JPG")
389  && (imagetypes() & IMG_JPG))
390  {
391  # add JPEG to list of supported formats
392  $Supported |= IMGTYPE_JPEG;
393  }
394 
395  # if GIF is supported by PHP
396  if (function_exists("imagetypes") && defined("IMG_GIF")
397  && (imagetypes() & IMG_GIF))
398  {
399  # add GIF to list of supported formats
400  $Supported |= IMGTYPE_GIF;
401  }
402 
403  # if PNG is supported by PHP
404  if (function_exists("imagetypes") && defined("IMG_PNG")
405  && (imagetypes() & IMG_PNG))
406  {
407  # add PNG to list of supported formats
408  $Supported |= IMGTYPE_PNG;
409  }
410 
411  # report to caller what formats are supported
412  return $Supported;
413  }
414 
415  # return names (upper-case extensions) of supported image formats
416  static function SupportedFormatNames()
417  {
418  # assume that no formats are supported
419  $FormatNames = array();
420 
421  # retrieve supported formats
422  $SupportedFormats = Image::SupportedFormats();
423 
424  # for each possible supported format
425  foreach (Image::$AxisImageFileExtensions as $ImageType => $ImageExtension)
426  {
427  # if format is supported
428  if ($ImageType & $SupportedFormats)
429  {
430  # add format extension to list of supported image format names
431  $FormatNames[] = strtoupper($ImageExtension);
432  }
433  }
434 
435  # return supported image format names to caller
436  return $FormatNames;
437  }
438 
439  # return the error status set by the constructor or the last call to SaveAs()
440  function Status()
441  {
442  return $this->ErrorStatus;
443  }
444 
445  # return string containing external command that failed
447  {
448  return $this->FailedCommand;
449  }
450 
451 
452  # ---- PRIVATE INTERFACE -------------------------------------------------
453 
471 
472  # image file extensions
473  private static $AxisImageFileExtensions = array(
474  IMGTYPE_JPEG => "jpg",
475  IMGTYPE_GIF => "gif",
476  IMGTYPE_BMP => "bmp",
477  IMGTYPE_PNG => "png",
478  );
479 
480  function ReadSize()
481  {
482  # if we do not already have image info
483  if (!isset($this->ImageXSize))
484  {
485  # read size information from image object
486  $this->ImageXSize = imagesx($this->ImageObj);
487  $this->ImageYSize = imagesy($this->ImageObj);
488  }
489  }
490 
491  function ImageFormatSupportedByPhp($Format = NULL)
492  {
493  if ($Format == NULL) { $Format = $this->Type(); }
494 
495  if (!function_exists("imagetypes")) { return FALSE; }
496 
497  switch ($Format)
498  {
499  case IMGTYPE_JPEG:
500  return (imagetypes() & IMG_JPG) ? TRUE : FALSE;
501  break;
502 
503  case IMGTYPE_GIF:
504  return (imagetypes() & IMG_GIF) ? TRUE : FALSE;
505  break;
506 
507  case IMGTYPE_BMP:
508  return FALSE;
509  break;
510 
511  case IMGTYPE_PNG:
512  return (imagetypes() & IMG_PNG) ? TRUE : FALSE;
513  break;
514 
515  default:
516  return FALSE;
517  break;
518  }
519  }
520 }
521 
522 # image type definitions (these are purposefully different from those defined by PHP GD lib)
523 define("IMGTYPE_UNKNOWN", 0);
524 define("IMGTYPE_JPEG", 1);
525 define("IMGTYPE_GIF", 2);
526 define("IMGTYPE_BMP", 4);
527 define("IMGTYPE_PNG", 8);
528 
529 # error status definitions
530 define("AI_OKAY", 0);
531 define("AI_FILEUNREADABLE", 1);
532 define("AI_IMGOBJCREATEFAILED", 2);
533 define("AI_PPMCMDFAILED", 4);
534 define("AI_INTERNALERROR", 8);
535 define("AI_UNKNOWNTYPE", 16);
536 define("AI_UNSUPPORTEDFORMAT", 32);
537 define("AI_DESTINATIONUNWRITABLE", 64);
538 
539 # supply imagetypes() function if not defined
540 if (!function_exists("imagetypes"))
541 {
542  # (returning 0 indicates no image types supported)
543  function imagetypes() { return 0; }
544 }
545 
static SupportedFormatNames()
SaveAs($FileName, $NewImageType=NULL)
const IMGTYPE_JPEG
ScaleTo($ScaledXSize, $ScaledYSize, $MaintainAspectRatio=FALSE)
CropTo($CroppedXSize, $CroppedYSize, $CroppedXOrigin=0, $CroppedYOrigin=0)
ReadSize()
$CroppedYOrigin
$DecodeCommand
const AI_IMGOBJCREATEFAILED
const IMGTYPE_BMP
const AI_FILEUNREADABLE
$CroppedXOrigin
$JpegSaveQuality
const AI_INTERNALERROR
Image($SourceFileName, $DebugLevel=0)
Definition: Axis--Image.php:19
PHP
Definition: OAIClient.php:39
JpegQuality($NewSetting=NULL)
ImageFormatSupportedByPhp($Format=NULL)
$MaintainAspectRatio
const IMGTYPE_PNG
const IMGTYPE_GIF
const IMGTYPE_UNKNOWN
const AI_OKAY
Mimetype()
Get the MIME type for the image.
const AI_DESTINATIONUNWRITABLE
Type($FileName=NULL)
static SupportedFormats()
FailedExternalCommand()
$FailedCommand
const AI_UNSUPPORTEDFORMAT
$SourceFileName
static Extension($Type=NULL)