[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

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

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


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7