web/drupal/includes/image.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: image.inc,v 1.24 2008/01/28 16:05:17 goba Exp $
       
     3 
       
     4 /**
       
     5  * @file
       
     6  * API for manipulating images.
       
     7  */
       
     8 
       
     9 /**
       
    10  * @defgroup image Image toolkits
       
    11  * @{
       
    12  * Drupal's image toolkits provide an abstraction layer for common image file
       
    13  * manipulations like scaling, cropping, and rotating. The abstraction frees
       
    14  * module authors from the need to support multiple image libraries, and it
       
    15  * allows site administrators to choose the library that's best for them.
       
    16  *
       
    17  * PHP includes the GD library by default so a GD toolkit is installed with
       
    18  * Drupal. Other toolkits like ImageMagic are available from contrib modules.
       
    19  * GD works well for small images, but using it with larger files may cause PHP
       
    20  * to run out of memory. In contrast the ImageMagick library does not suffer
       
    21  * from this problem, but it requires the ISP to have installed additional
       
    22  * software.
       
    23  *
       
    24  * Image toolkits are installed by copying the image.ToolkitName.inc file into
       
    25  * Drupal's includes directory. The toolkit must then be enabled using the
       
    26  * admin/settings/image-toolkit form.
       
    27  *
       
    28  * Only one toolkit maybe selected at a time. If a module author wishes to call
       
    29  * a specific toolkit they can check that it is installed by calling
       
    30  * image_get_available_toolkits(), and then calling its functions directly.
       
    31  */
       
    32 
       
    33 /**
       
    34  * Return a list of available toolkits.
       
    35  *
       
    36  * @return
       
    37  *   An array of toolkit name => descriptive title.
       
    38  */
       
    39 function image_get_available_toolkits() {
       
    40   $toolkits = file_scan_directory('includes', 'image\..*\.inc$');
       
    41 
       
    42   $output = array();
       
    43   foreach ($toolkits as $file => $toolkit) {
       
    44     include_once "./$file";
       
    45     $function = str_replace('.', '_', $toolkit->name) .'_info';
       
    46     if (function_exists($function)) {
       
    47       $info = $function();
       
    48       $output[$info['name']] = $info['title'];
       
    49     }
       
    50   }
       
    51 
       
    52   return $output;
       
    53 }
       
    54 
       
    55 /**
       
    56  * Retrieve the name of the currently used toolkit.
       
    57  *
       
    58  * @return
       
    59  *   String containing the name of the selected toolkit, or FALSE on error.
       
    60  */
       
    61 function image_get_toolkit() {
       
    62   static $toolkit;
       
    63 
       
    64   if (!$toolkit) {
       
    65     $toolkit = variable_get('image_toolkit', 'gd');
       
    66     $toolkit_file = './includes/image.'. $toolkit .'.inc';
       
    67     if (isset($toolkit) && file_exists($toolkit_file)) {
       
    68       include_once $toolkit_file;
       
    69     }
       
    70     elseif (!image_gd_check_settings()) {
       
    71       $toolkit = FALSE;
       
    72     }
       
    73   }
       
    74 
       
    75   return $toolkit;
       
    76 }
       
    77 
       
    78 /**
       
    79  * Invokes the given method using the currently selected toolkit.
       
    80  *
       
    81  * @param $method
       
    82  *   A string containing the method to invoke.
       
    83  * @param $params
       
    84  *   An optional array of parameters to pass to the toolkit method.
       
    85  * @return
       
    86  *   Mixed values (typically Boolean indicating successful operation).
       
    87  */
       
    88 function image_toolkit_invoke($method, $params = array()) {
       
    89   if ($toolkit = image_get_toolkit()) {
       
    90     $function = 'image_'. $toolkit .'_'. $method;
       
    91     if (function_exists($function)) {
       
    92       return call_user_func_array($function, $params);
       
    93     }
       
    94     else {
       
    95       watchdog('php', 'The selected image handling toolkit %toolkit can not correctly process %function.', array('%toolkit' => $toolkit, '%function' => $function), WATCHDOG_ERROR);
       
    96       return FALSE;
       
    97     }
       
    98   }
       
    99 }
       
   100 
       
   101 
       
   102 /**
       
   103  * Get details about an image.
       
   104  *
       
   105  * Drupal only supports GIF, JPG and PNG file formats.
       
   106  *
       
   107  * @return
       
   108  *   FALSE, if the file could not be found or is not an image. Otherwise, a
       
   109  *   keyed array containing information about the image:
       
   110  *    'width'     - Width in pixels.
       
   111  *    'height'    - Height in pixels.
       
   112  *    'extension' - Commonly used file extension for the image.
       
   113  *    'mime_type' - MIME type ('image/jpeg', 'image/gif', 'image/png').
       
   114  *    'file_size' - File size in bytes.
       
   115  */
       
   116 function image_get_info($file) {
       
   117   if (!is_file($file)) {
       
   118     return FALSE;
       
   119   }
       
   120 
       
   121   $details = FALSE;
       
   122   $data = @getimagesize($file);
       
   123   $file_size = @filesize($file);
       
   124 
       
   125   if (isset($data) && is_array($data)) {
       
   126     $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png');
       
   127     $extension = array_key_exists($data[2], $extensions) ?  $extensions[$data[2]] : '';
       
   128     $details = array('width'     => $data[0],
       
   129                      'height'    => $data[1],
       
   130                      'extension' => $extension,
       
   131                      'file_size' => $file_size,
       
   132                      'mime_type' => $data['mime']);
       
   133   }
       
   134 
       
   135   return $details;
       
   136 }
       
   137 
       
   138 /**
       
   139  * Scales an image to the exact width and height given. Achieves the
       
   140  * target aspect ratio by cropping the original image equally on both
       
   141  * sides, or equally on the top and bottom.  This function is, for
       
   142  * example, useful to create uniform sized avatars from larger images.
       
   143  *
       
   144  * The resulting image always has the exact target dimensions.
       
   145  *
       
   146  * @param $source
       
   147  *   The file path of the source image.
       
   148  * @param $destination
       
   149  *   The file path of the destination image.
       
   150  * @param $width
       
   151  *   The target width, in pixels.
       
   152  * @param $height
       
   153  *   The target height, in pixels.
       
   154  * @return
       
   155  *   TRUE or FALSE, based on success.
       
   156  */
       
   157 function image_scale_and_crop($source, $destination, $width, $height) {
       
   158   $info = image_get_info($source);
       
   159 
       
   160   $scale = max($width / $info['width'], $height / $info['height']);
       
   161   $x = round(($info['width'] * $scale - $width) / 2);
       
   162   $y = round(($info['height'] * $scale - $height) / 2);
       
   163 
       
   164   if (image_toolkit_invoke('resize', array($source, $destination, $info['width'] * $scale, $info['height'] * $scale))) {
       
   165     return image_toolkit_invoke('crop', array($destination, $destination, $x, $y, $width, $height));
       
   166   }
       
   167   return FALSE;
       
   168 }
       
   169 
       
   170 /**
       
   171  * Scales an image to the given width and height while maintaining aspect
       
   172  * ratio.
       
   173  *
       
   174  * The resulting image can be smaller for one or both target dimensions.
       
   175  *
       
   176  * @param $source
       
   177  *   The file path of the source image.
       
   178  * @param $destination
       
   179  *   The file path of the destination image.
       
   180  * @param $width
       
   181  *   The target width, in pixels.
       
   182  * @param $height
       
   183  *   The target height, in pixels.
       
   184  * @return
       
   185  *   TRUE or FALSE, based on success.
       
   186  */
       
   187 function image_scale($source, $destination, $width, $height) {
       
   188   $info = image_get_info($source);
       
   189 
       
   190   // Don't scale up.
       
   191   if ($width >= $info['width'] && $height >= $info['height']) {
       
   192     return FALSE;
       
   193   }
       
   194 
       
   195   $aspect = $info['height'] / $info['width'];
       
   196   if ($aspect < $height / $width) {
       
   197     $width = (int)min($width, $info['width']);
       
   198     $height = (int)round($width * $aspect);
       
   199   }
       
   200   else {
       
   201     $height = (int)min($height, $info['height']);
       
   202     $width = (int)round($height / $aspect);
       
   203   }
       
   204 
       
   205   return image_toolkit_invoke('resize', array($source, $destination, $width, $height));
       
   206 }
       
   207 
       
   208 /**
       
   209  * Resize an image to the given dimensions (ignoring aspect ratio).
       
   210  *
       
   211  * @param $source
       
   212  *   The file path of the source image.
       
   213  * @param $destination
       
   214  *   The file path of the destination image.
       
   215  * @param $width
       
   216  *   The target width, in pixels.
       
   217  * @param $height
       
   218  *   The target height, in pixels.
       
   219   * @return
       
   220  *   TRUE or FALSE, based on success.
       
   221  */
       
   222 function image_resize($source, $destination, $width, $height) {
       
   223   return image_toolkit_invoke('resize', array($source, $destination, $width, $height));
       
   224 }
       
   225 
       
   226 /**
       
   227  * Rotate an image by the given number of degrees.
       
   228  *
       
   229  * @param $source
       
   230  *   The file path of the source image.
       
   231  * @param $destination
       
   232  *   The file path of the destination image.
       
   233  * @param $degrees
       
   234  *   The number of (clockwise) degrees to rotate the image.
       
   235  * @param $background
       
   236  *   An hexidecimal integer specifying the background color to use for the
       
   237  *   uncovered area of the image after the rotation. E.g. 0x000000 for black,
       
   238  *   0xff00ff for magenta, and 0xffffff for white.
       
   239  * @return
       
   240  *   TRUE or FALSE, based on success.
       
   241  */
       
   242 function image_rotate($source, $destination, $degrees, $background = 0x000000) {
       
   243   return image_toolkit_invoke('rotate', array($source, $destination, $degrees, $background));
       
   244 }
       
   245 
       
   246 /**
       
   247  * Crop an image to the rectangle specified by the given rectangle.
       
   248  *
       
   249  * @param $source
       
   250  *   The file path of the source image.
       
   251  * @param $destination
       
   252  *   The file path of the destination image.
       
   253  * @param $x
       
   254  *   The top left co-ordinate, in pixels, of the crop area (x axis value).
       
   255  * @param $y
       
   256  *   The top left co-ordinate, in pixels, of the crop area (y axis value).
       
   257  * @param $width
       
   258  *   The target width, in pixels.
       
   259  * @param $height
       
   260  *   The target height, in pixels.
       
   261  * @return
       
   262  *   TRUE or FALSE, based on success.
       
   263  */
       
   264 function image_crop($source, $destination, $x, $y, $width, $height) {
       
   265   return image_toolkit_invoke('crop', array($source, $destination, $x, $y, $width, $height));
       
   266 }
       
   267 
       
   268 /**
       
   269  * @} End of "defgroup image".
       
   270  */