[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/imageapi/ -> imageapi.module (source)

   1  <?php
   2  // $Id: imageapi.module,v 1.23.2.4 2010/04/30 21:48:38 drewish Exp $
   3  
   4  /**
   5   * @file
   6   *
   7   * An ImageAPI supporting additional image plugins as modules.
   8   * Images are treated as objects, and images are not written per
   9   * manipulation as Drupal's core image handling works.
  10   *
  11   *
  12   * imageapi image api workflow...
  13   * $image = imageapi_image_open($path) to get an image object for $path...
  14   * image_X($image, $arg1, $arg2)  to manipulate image object...
  15   * imageapi_image_close($image) to overwrite original image.
  16   *
  17   */
  18  
  19  /**
  20   * Implementation of hook_perm().
  21   */
  22  function imageapi_perm() {
  23    return array('administer imageapi');
  24  }
  25  
  26  /**
  27   * Implementation of hook_menu().
  28   */
  29  function imageapi_menu() {
  30    $items = array();
  31    $items['admin/settings/imageapi'] = array(
  32      'title' => 'ImageAPI',
  33      'description' => 'Configure ImageAPI.',
  34      'page callback' => 'drupal_get_form',
  35      'page arguments' => array('imageapi_settings'),
  36      'access arguments' => array('administer imageapi'),
  37    );
  38  
  39    $toolkits = imageapi_get_available_toolkits();
  40    if ($toolkits) {
  41      $items['admin/settings/imageapi/list'] = array(
  42        'title' => 'List',
  43        'type' => MENU_DEFAULT_LOCAL_TASK,
  44        'weight' => -1,
  45      );
  46      $items['admin/settings/imageapi/config'] = array(
  47        'title' => 'Configure',
  48        'type' => MENU_LOCAL_TASK,
  49        'page callback' => 'drupal_get_form',
  50        'page arguments' => array(imageapi_default_toolkit() .'_settings_form'),
  51        'access arguments' => array('administer imageapi'),
  52      );
  53      foreach ($toolkits as $module => $info) {
  54        if (function_exists($module .'_settings_form')) {
  55          $items['admin/settings/imageapi/config/'. $module] = array(
  56            'title' => '@name',
  57            'title arguments' => array('@name' => $info['name']),
  58            'page callback' => 'drupal_get_form',
  59            'page arguments' => array($module .'_settings_form'),
  60            'access arguments' => array('administer imageapi'),
  61            'type' => $module == imageapi_default_toolkit() ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
  62          );
  63        }
  64        else {
  65          drupal_set_message(t('ImageAPI toolkit missing settings form'), 'error');
  66        }
  67      }
  68    }
  69    return $items;
  70  }
  71  
  72  function imageapi_settings() {
  73    $form = array();
  74  
  75    $toolkits = imageapi_get_available_toolkits();
  76  
  77    switch (count($toolkits)) {
  78      case 0:
  79        $form['imageapi_toolkits']['#value'] = t('There are no image toolkit modules enabled. Toolkit modules can be enabled from the <a href="!admin-build-modules">module configuration page</a>.', array('!admin-build-modules' => url('admin/build/modules')));
  80        return $form;
  81  
  82      case 1:
  83        $toolkit = key($toolkits);
  84        // The variable needs to be manually set. Otherwise, if a user has two
  85        // toolkits and disables the selected one they won't be able to select the
  86        // remaing toolkit.
  87        variable_set('imageapi_image_toolkit', $toolkit);
  88        $form['imageapi_image_toolkit']['#value'] = t('The %toolkit module is the only enabled image toolkit. Drupal will use it for resizing, cropping and other image manipulations.', array('%toolkit' => $toolkits[$toolkit]['name']));
  89        return $form;
  90  
  91      default:
  92        $options = array();
  93        foreach ($toolkits as $module => $info) {
  94          $options[$module] = $info['name'];
  95        }
  96        $form['imageapi_image_toolkit'] = array(
  97          '#type' => 'radios',
  98          '#title' => t('Select a default image processing toolkit'),
  99          '#default_value' => imageapi_default_toolkit(),
 100          '#options' => $options,
 101          '#description' => t('This setting lets you choose which toolkit Drupal uses resizing, cropping and other image manipulations.'),
 102        );
 103    }
 104  
 105    return system_settings_form($form);
 106  }
 107  
 108  /**
 109   * Return a list of available toolkits.
 110   *
 111   * @return
 112   *   An array of the enabled image toolkit modules. The module name is the key
 113   *   and the value is a sub-array with the module's 'name' and 'description'.
 114   */
 115  function imageapi_get_available_toolkits() {
 116    static $toolkits;
 117  
 118    if (!isset($toolkits)) {
 119      $toolkits = array();
 120      foreach (module_implements('imageapi_toolkit', TRUE) as $module) {
 121        $info = drupal_parse_info_file(drupal_get_path('module', $module) .'/'. $module .'.info');
 122        $toolkits[$module] = array('name' => $info['name'], 'description' => $info['description']);
 123      }
 124    }
 125  
 126    return $toolkits;
 127  }
 128  
 129  /**
 130   * Retrieve the name of the currently used toolkit.
 131   *
 132   * @return
 133   *   String containing the name of the toolkit, or FALSE if none is available.
 134   */
 135  function imageapi_default_toolkit() {
 136    $toolkit = variable_get('imageapi_image_toolkit', 'imageapi_gd');
 137    // Verify that the image toolkit is available.
 138    if (isset($toolkit) && module_exists($toolkit)) {
 139      return $toolkit;
 140    }
 141    // If it's not fall back to first available toolist.
 142    foreach (imageapi_get_available_toolkits() as $toolkit => $info) {
 143      return $toolkit;
 144    }
 145    return FALSE;
 146  }
 147  
 148  
 149  /**
 150   * Invokes the given method using the currently selected toolkit.
 151   *
 152   * @param $method
 153   *   A string containing the method to invoke.
 154   * @param $image
 155   *   An image object returned by imageapi_image_open().
 156   * @param $params
 157   *   An optional array of parameters to pass to the toolkit method.
 158   * @return
 159   *   Mixed values (typically Boolean indicating successful operation).
 160   */
 161  function imageapi_toolkit_invoke($method, &$image, array $params = array()) {
 162    $function = $image->toolkit . '_image_' . $method;
 163    if (function_exists($function)) {
 164      array_unshift($params, $image);
 165      $params[0] = &$image;
 166      return call_user_func_array($function, $params);
 167    }
 168    watchdog('imageapi', 'The selected image handling toolkit %toolkit can not correctly process %function.', array('%toolkit' => $image->toolkit, '%function' => $function), WATCHDOG_ERROR);
 169    return FALSE;
 170  }
 171  
 172  /**
 173   * Scales an image to the exact width and height given.
 174   *
 175   * This function achieves the target aspect ratio by cropping the original image
 176   * equally on both sides, or equally on the top and bottom. This function is
 177   * useful to create uniform sized avatars from larger images.
 178   *
 179   * The resulting image always has the exact target dimensions.
 180   *
 181   * @param $image
 182   *   An image object returned by imageapi_image_open().
 183   * @param $width
 184   *   The target width, in pixels.
 185   * @param $height
 186   *   The target height, in pixels.
 187   * @return
 188   *   TRUE or FALSE, based on success.
 189   */
 190  function imageapi_image_scale_and_crop(&$image, $width, $height) {
 191    $scale = max($width / $image->info['width'], $height / $image->info['height']);
 192    $x = ($image->info['width'] * $scale - $width) / 2;
 193    $y = ($image->info['height'] * $scale - $height) / 2;
 194  
 195    if (imageapi_image_resize($image, $image->info['width'] * $scale, $image->info['height'] * $scale)) {
 196      return imageapi_image_crop($image, $x, $y, $width, $height);
 197    }
 198    return FALSE;
 199  }
 200  
 201  /**
 202   * Scales an image to the given width and height while maintaining aspect
 203   * ratio.
 204   *
 205   * The resulting image can be smaller for one or both target dimensions.
 206   *
 207   * @param $image
 208   *   An image object returned by imageapi_image_open().
 209   * @param $width
 210   *   The target width, in pixels. This value is omitted then the scaling will
 211   *   based only on the height value.
 212   * @param $height
 213   *   The target height, in pixels. This value is omitted then the scaling will
 214   *   based only on the width value.
 215   * @param $upscale
 216   *   Boolean indicating that files smaller than the dimensions will be scalled
 217   *   up. This generally results in a low quality image.
 218   * @return
 219   *   TRUE or FALSE, based on success.
 220   */
 221  function imageapi_image_scale(&$image, $width = NULL, $height = NULL, $upscale = FALSE) {
 222    $aspect = $image->info['height'] / $image->info['width'];
 223  
 224    if ($upscale) {
 225      // Set width/height according to aspect ratio if either is empty.
 226      $width = !empty($width) ? $width : $height / $aspect;
 227      $height = !empty($height) ? $height : $width / $aspect;
 228    }
 229    else {
 230      // Set impossibly large values if the width and height aren't set.
 231      $width = !empty($width) ? $width : 9999999;
 232      $height = !empty($height) ? $height : 9999999;
 233  
 234      // Don't scale up.
 235      if (round($width) >= $image->info['width'] && round($height) >= $image->info['height']) {
 236        return TRUE;
 237      }
 238    }
 239  
 240    if ($aspect < $height / $width) {
 241      $height = $width * $aspect;
 242    }
 243    else {
 244      $width = $height / $aspect;
 245    }
 246  
 247    return imageapi_image_resize($image, $width, $height);
 248  }
 249  
 250  /**
 251   * Resize an image to the given dimensions (ignoring aspect ratio).
 252   *
 253   * @param $image
 254   *   An image object returned by imageapi_image_open().
 255   * @param $width
 256   *   The target width, in pixels.
 257   * @param $height
 258   *   The target height, in pixels.
 259   * @return
 260   *   TRUE or FALSE, based on success.
 261   */
 262  function imageapi_image_resize(&$image, $width, $height) {
 263    $width = (int) round($width);
 264    $height = (int) round($height);
 265  
 266    return imageapi_toolkit_invoke('resize', $image, array($width, $height));
 267  }
 268  
 269  /**
 270   * Rotate an image by the given number of degrees.
 271   *
 272   * @param $image
 273   *   An image object returned by imageapi_image_open().
 274   * @param $degrees
 275   *   The number of (clockwise) degrees to rotate the image.
 276   * @param $background
 277   *   An hexadecimal integer specifying the background color to use for the
 278   *   uncovered area of the image after the rotation. E.g. 0x000000 for black,
 279   *   0xff00ff for magenta, and 0xffffff for white. For images that support
 280   *   transparency, this will default to transparent. Otherwise it will
 281   *   be white.
 282   * @return
 283   *   TRUE or FALSE, based on success.
 284   */
 285  function imageapi_image_rotate(&$image, $degrees, $background = NULL) {
 286    return imageapi_toolkit_invoke('rotate', $image, array($degrees, $background));
 287  }
 288  
 289  /**
 290   * Sharpen an image given some sharpening parameters.
 291   *
 292   * NOTE: These parameters only have an effect when Imagemagick is used.
 293   *       GD will used a fixed convolution matrix as described in imageapi_gd.module
 294   *
 295   * @param $image
 296   *   An imageapi image object returned by imageapi_image_open().
 297   * @param $radius
 298   *   The radius of the gaussian, in pixels, not counting the center pixel. (default 0.5)
 299   * @param $sigma
 300   *   The standard deviation of the gaussian, in pixels. (default 0.5)
 301   * @param $amount
 302   *   The percentage of the difference between the original and the blur image that is
 303   *   added back into the original. (default 100)
 304   * @param $threshold
 305   *   The threshold, as a fraction of max RGB levels, needed to apply the difference
 306   *   amount. (default 0.05)
 307   * @return
 308   *   True or FALSE, based on success.
 309   */
 310  function imageapi_image_sharpen(&$image, $radius, $sigma, $amount, $threshold) {
 311    return imageapi_toolkit_invoke('sharpen', $image, array($radius, $sigma, $amount, $threshold));
 312  }
 313  
 314  /**
 315   * Crop an image to the rectangle specified by the given rectangle.
 316   *
 317   * @param $image
 318   *   An image object returned by imageapi_image_open().
 319   * @param $x
 320   *   The top left coordinate, in pixels, of the crop area (x axis value).
 321   * @param $y
 322   *   The top left coordinate, in pixels, of the crop area (y axis value).
 323   * @param $width
 324   *   The target width, in pixels.
 325   * @param $height
 326   *   The target height, in pixels.
 327   * @return
 328   *   TRUE or FALSE, based on success.
 329   */
 330  function imageapi_image_crop(&$image, $x, $y, $width, $height) {
 331    $aspect = $image->info['height'] / $image->info['width'];
 332    if (empty($height)) $height = $width / $aspect;
 333    if (empty($width)) $width = $height * $aspect;
 334  
 335    $width = (int) round($width);
 336    $height = (int) round($height);
 337  
 338    return imageapi_toolkit_invoke('crop', $image, array($x, $y, $width, $height));
 339  }
 340  
 341  /**
 342   * Convert an image to grayscale.
 343   *
 344   * @param $image
 345   *   An image object returned by imageapi_image_open().
 346   * @return
 347   *   TRUE or FALSE, based on success.
 348   */
 349  function imageapi_image_desaturate(&$image) {
 350    return imageapi_toolkit_invoke('desaturate', $image);
 351  }
 352  
 353  /**
 354   * Open an image file and return an image object.
 355   *
 356   * Any changes to the file are not saved until imageapi_image_close() is called.
 357   *
 358   * @param $file
 359   *   Path to an image file.
 360   * @param $toolkit
 361   *   An optional, image toolkit name to override the default.
 362   * @return
 363   *   An image object or FALSE if there was a problem loading the file. The
 364   *   image object has the following properties:
 365   *    - 'source' - The original file path.
 366   *    - 'info' - The array of information returned by image_get_info()
 367   *    - 'toolkit' - The name of the image toolkit requested when the image was
 368   *      loaded.
 369   *   Image tookits may add additional properties. The caller is advised not to
 370   *   monkey about with them.
 371   */
 372  function imageapi_image_open($file, $toolkit = FALSE) {
 373    if (!$toolkit) {
 374      $toolkit = imageapi_default_toolkit();
 375    }
 376    if ($toolkit) {
 377      $image = new stdClass();
 378      $image->source = $file;
 379      $image->info = image_get_info($file);
 380      $image->toolkit = $toolkit;
 381      if (imageapi_toolkit_invoke('open', $image)) {
 382        return $image;
 383      }
 384    }
 385    return FALSE;
 386  }
 387  
 388  /**
 389   * Close the image and save the changes to a file.
 390   *
 391   * @param $image
 392   *   An image object returned by imageapi_image_open(). The object's 'info'
 393   *   property will be updated if the file is saved successfully.
 394   * @param $destination
 395   *   Destination path where the image should be saved. If it is empty the
 396   *   original image file will be overwritten.
 397   * @return
 398   *   TRUE or FALSE, based on success.
 399   */
 400  function imageapi_image_close($image, $destination = NULL) {
 401    if (empty($destination)) {
 402      $destination = $image->source;
 403    }
 404    if ($return = imageapi_toolkit_invoke('close', $image, array($destination))) {
 405      // Clear the cached file size and refresh the image information.
 406      clearstatcache();
 407      $image->info = image_get_info($destination);
 408  
 409      if (@chmod($destination, 0664)) {
 410        return $return;
 411      }
 412      watchdog('imageapi', 'Could not set permissions on destination file: %file', array('%file' => $destination));
 413    }
 414    return FALSE;
 415  }
 416  
 417  
 418  /**
 419   * Convert a hex string to its RGBA (Red, Green, Blue, Alpha) integer
 420   * components.
 421   *
 422   * @param $hex
 423   *   A string specifing an RGB color in the formats:
 424   *   '#ABC','ABC','#ABCD','ABCD','#AABBCC','AABBCC','#AABBCCDD','AABBCCDD'
 425   * @return
 426   *   An array with four elements for red, green, blue, and alpha.
 427   */
 428  function imageapi_hex2rgba($hex) {
 429    $hex = ltrim($hex, '#');
 430    if (preg_match('/^[0-9a-f]{3}$/i', $hex)) {
 431      // 'FA3' is the same as 'FFAA33' so r=FF, g=AA, b=33
 432      $r = str_repeat($hex{0}, 2);
 433      $g = str_repeat($hex{1}, 2);
 434      $b = str_repeat($hex{2}, 2);
 435      $a = '0';
 436    }
 437    elseif (preg_match('/^[0-9a-f]{6}$/i', $hex)) {
 438      // #FFAA33 or r=FF, g=AA, b=33
 439      list($r, $g, $b) = str_split($hex, 2);
 440      $a = '0';
 441    }
 442    elseif (preg_match('/^[0-9a-f]{8}$/i', $hex)) {
 443      // #FFAA33 or r=FF, g=AA, b=33
 444      list($r, $g, $b, $a) = str_split($hex, 2);
 445    }
 446    elseif (preg_match('/^[0-9a-f]{4}$/i', $hex)) {
 447      // 'FA37' is the same as 'FFAA3377' so r=FF, g=AA, b=33, a=77
 448      $r = str_repeat($hex{0}, 2);
 449      $g = str_repeat($hex{1}, 2);
 450      $b = str_repeat($hex{2}, 2);
 451      $a = str_repeat($hex{3}, 2);
 452    }
 453    else {
 454      //error: invalide hex string, TODO: set form error..
 455      return FALSE;
 456    }
 457  
 458    $r = hexdec($r);
 459    $g = hexdec($g);
 460    $b = hexdec($b);
 461    $a = hexdec($a);
 462    return array($r, $g, $b, $a);
 463  }
 464  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7