cms/drupal/modules/image/image.effects.inc
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Functions needed to execute image effects provided by Image module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Implements hook_image_effect_info().
       
    10  */
       
    11 function image_image_effect_info() {
       
    12   $effects = array(
       
    13     'image_resize' => array(
       
    14       'label' => t('Resize'),
       
    15       'help' => t('Resizing will make images an exact set of dimensions. This may cause images to be stretched or shrunk disproportionately.'),
       
    16       'effect callback' => 'image_resize_effect',
       
    17       'dimensions callback' => 'image_resize_dimensions',
       
    18       'form callback' => 'image_resize_form',
       
    19       'summary theme' => 'image_resize_summary',
       
    20     ),
       
    21     'image_scale' => array(
       
    22       'label' => t('Scale'),
       
    23       'help' => t('Scaling will maintain the aspect-ratio of the original image. If only a single dimension is specified, the other dimension will be calculated.'),
       
    24       'effect callback' => 'image_scale_effect',
       
    25       'dimensions callback' => 'image_scale_dimensions',
       
    26       'form callback' => 'image_scale_form',
       
    27       'summary theme' => 'image_scale_summary',
       
    28     ),
       
    29     'image_scale_and_crop' => array(
       
    30       'label' => t('Scale and crop'),
       
    31       'help' => t('Scale and crop will maintain the aspect-ratio of the original image, then crop the larger dimension. This is most useful for creating perfectly square thumbnails without stretching the image.'),
       
    32       'effect callback' => 'image_scale_and_crop_effect',
       
    33       'dimensions callback' => 'image_resize_dimensions',
       
    34       'form callback' => 'image_resize_form',
       
    35       'summary theme' => 'image_resize_summary',
       
    36     ),
       
    37     'image_crop' => array(
       
    38       'label' => t('Crop'),
       
    39       'help' => t('Cropping will remove portions of an image to make it the specified dimensions.'),
       
    40       'effect callback' => 'image_crop_effect',
       
    41       'dimensions callback' => 'image_resize_dimensions',
       
    42       'form callback' => 'image_crop_form',
       
    43       'summary theme' => 'image_crop_summary',
       
    44     ),
       
    45     'image_desaturate' => array(
       
    46       'label' => t('Desaturate'),
       
    47       'help' => t('Desaturate converts an image to grayscale.'),
       
    48       'effect callback' => 'image_desaturate_effect',
       
    49       'dimensions passthrough' => TRUE,
       
    50     ),
       
    51     'image_rotate' => array(
       
    52       'label' => t('Rotate'),
       
    53       'help' => t('Rotating an image may cause the dimensions of an image to increase to fit the diagonal.'),
       
    54       'effect callback' => 'image_rotate_effect',
       
    55       'dimensions callback' => 'image_rotate_dimensions',
       
    56       'form callback' => 'image_rotate_form',
       
    57       'summary theme' => 'image_rotate_summary',
       
    58     ),
       
    59   );
       
    60 
       
    61   return $effects;
       
    62 }
       
    63 
       
    64 /**
       
    65  * Image effect callback; Resize an image resource.
       
    66  *
       
    67  * @param $image
       
    68  *   An image object returned by image_load().
       
    69  * @param $data
       
    70  *   An array of attributes to use when performing the resize effect with the
       
    71  *   following items:
       
    72  *   - "width": An integer representing the desired width in pixels.
       
    73  *   - "height": An integer representing the desired height in pixels.
       
    74  *
       
    75  * @return
       
    76  *   TRUE on success. FALSE on failure to resize image.
       
    77  *
       
    78  * @see image_resize()
       
    79  */
       
    80 function image_resize_effect(&$image, $data) {
       
    81   if (!image_resize($image, $data['width'], $data['height'])) {
       
    82     watchdog('image', 'Image resize failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
       
    83     return FALSE;
       
    84   }
       
    85   return TRUE;
       
    86 }
       
    87 
       
    88 /**
       
    89  * Image dimensions callback; Resize.
       
    90  *
       
    91  * @param $dimensions
       
    92  *   Dimensions to be modified - an array with components width and height, in
       
    93  *   pixels.
       
    94  * @param $data
       
    95  *   An array of attributes to use when performing the resize effect with the
       
    96  *   following items:
       
    97  *   - "width": An integer representing the desired width in pixels.
       
    98  *   - "height": An integer representing the desired height in pixels.
       
    99  */
       
   100 function image_resize_dimensions(array &$dimensions, array $data) {
       
   101   // The new image will have the exact dimensions defined for the effect.
       
   102   $dimensions['width'] = $data['width'];
       
   103   $dimensions['height'] = $data['height'];
       
   104 }
       
   105 
       
   106 /**
       
   107  * Image effect callback; Scale an image resource.
       
   108  *
       
   109  * @param $image
       
   110  *   An image object returned by image_load().
       
   111  * @param $data
       
   112  *   An array of attributes to use when performing the scale effect with the
       
   113  *   following items:
       
   114  *   - "width": An integer representing the desired width in pixels.
       
   115  *   - "height": An integer representing the desired height in pixels.
       
   116  *   - "upscale": A boolean indicating that the image should be upscaled if the
       
   117  *     dimensions are larger than the original image.
       
   118  *
       
   119  * @return
       
   120  *   TRUE on success. FALSE on failure to scale image.
       
   121  *
       
   122  * @see image_scale()
       
   123  */
       
   124 function image_scale_effect(&$image, $data) {
       
   125   // Set sane default values.
       
   126   $data += array(
       
   127     'width' => NULL,
       
   128     'height' => NULL,
       
   129     'upscale' => FALSE,
       
   130   );
       
   131 
       
   132   if (!image_scale($image, $data['width'], $data['height'], $data['upscale'])) {
       
   133     watchdog('image', 'Image scale failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
       
   134     return FALSE;
       
   135   }
       
   136   return TRUE;
       
   137 }
       
   138 
       
   139 /**
       
   140  * Image dimensions callback; Scale.
       
   141  *
       
   142  * @param $dimensions
       
   143  *   Dimensions to be modified - an array with components width and height, in
       
   144  *   pixels.
       
   145  * @param $data
       
   146  *   An array of attributes to use when performing the scale effect with the
       
   147  *   following items:
       
   148  *   - "width": An integer representing the desired width in pixels.
       
   149  *   - "height": An integer representing the desired height in pixels.
       
   150  *   - "upscale": A boolean indicating that the image should be upscaled if the
       
   151  *     dimensions are larger than the original image.
       
   152  */
       
   153 function image_scale_dimensions(array &$dimensions, array $data) {
       
   154   if ($dimensions['width'] && $dimensions['height']) {
       
   155     image_dimensions_scale($dimensions, $data['width'], $data['height'], $data['upscale']);
       
   156   }
       
   157 }
       
   158 
       
   159 /**
       
   160  * Image effect callback; Crop an image resource.
       
   161  *
       
   162  * @param $image
       
   163  *   An image object returned by image_load().
       
   164  * @param $data
       
   165  *   An array of attributes to use when performing the crop effect with the
       
   166  *   following items:
       
   167  *   - "width": An integer representing the desired width in pixels.
       
   168  *   - "height": An integer representing the desired height in pixels.
       
   169  *   - "anchor": A string describing where the crop should originate in the form
       
   170  *     of "XOFFSET-YOFFSET". XOFFSET is either a number of pixels or
       
   171  *     "left", "center", "right" and YOFFSET is either a number of pixels or
       
   172  *     "top", "center", "bottom".
       
   173  * @return
       
   174  *   TRUE on success. FALSE on failure to crop image.
       
   175  * @see image_crop()
       
   176  */
       
   177 function image_crop_effect(&$image, $data) {
       
   178   // Set sane default values.
       
   179   $data += array(
       
   180     'anchor' => 'center-center',
       
   181   );
       
   182 
       
   183   list($x, $y) = explode('-', $data['anchor']);
       
   184   $x = image_filter_keyword($x, $image->info['width'], $data['width']);
       
   185   $y = image_filter_keyword($y, $image->info['height'], $data['height']);
       
   186   if (!image_crop($image, $x, $y, $data['width'], $data['height'])) {
       
   187     watchdog('image', 'Image crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
       
   188     return FALSE;
       
   189   }
       
   190   return TRUE;
       
   191 }
       
   192 
       
   193 /**
       
   194  * Image effect callback; Scale and crop an image resource.
       
   195  *
       
   196  * @param $image
       
   197  *   An image object returned by image_load().
       
   198  * @param $data
       
   199  *   An array of attributes to use when performing the scale and crop effect
       
   200  *   with the following items:
       
   201  *   - "width": An integer representing the desired width in pixels.
       
   202  *   - "height": An integer representing the desired height in pixels.
       
   203  * @return
       
   204  *   TRUE on success. FALSE on failure to scale and crop image.
       
   205  * @see image_scale_and_crop()
       
   206  */
       
   207 function image_scale_and_crop_effect(&$image, $data) {
       
   208   if (!image_scale_and_crop($image, $data['width'], $data['height'])) {
       
   209     watchdog('image', 'Image scale and crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
       
   210     return FALSE;
       
   211   }
       
   212   return TRUE;
       
   213 }
       
   214 
       
   215 /**
       
   216  * Image effect callback; Desaturate (grayscale) an image resource.
       
   217  *
       
   218  * @param $image
       
   219  *   An image object returned by image_load().
       
   220  * @param $data
       
   221  *   An array of attributes to use when performing the desaturate effect.
       
   222  * @return
       
   223  *   TRUE on success. FALSE on failure to desaturate image.
       
   224  * @see image_desaturate()
       
   225  */
       
   226 function image_desaturate_effect(&$image, $data) {
       
   227   if (!image_desaturate($image)) {
       
   228     watchdog('image', 'Image desaturate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
       
   229     return FALSE;
       
   230   }
       
   231   return TRUE;
       
   232 }
       
   233 
       
   234 /**
       
   235  * Image effect callback; Rotate an image resource.
       
   236  *
       
   237  * @param $image
       
   238  *   An image object returned by image_load().
       
   239  * @param $data
       
   240  *   An array of attributes to use when performing the rotate effect containing
       
   241  *   the following items:
       
   242  *   - "degrees": The number of (clockwise) degrees to rotate the image.
       
   243  *   - "random": A boolean indicating that a random rotation angle should be
       
   244  *     used for this image. The angle specified in "degrees" is used as a
       
   245  *     positive and negative maximum.
       
   246  *   - "bgcolor": The background color to use for exposed areas of the image.
       
   247  *     Use web-style hex colors (#FFFFFF for white, #000000 for black). Leave
       
   248  *     blank for transparency on image types that support it.
       
   249  * @return
       
   250  *   TRUE on success. FALSE on failure to rotate image.
       
   251  * @see image_rotate().
       
   252  */
       
   253 function image_rotate_effect(&$image, $data) {
       
   254   // Set sane default values.
       
   255   $data += array(
       
   256     'degrees' => 0,
       
   257     'bgcolor' => NULL,
       
   258     'random' => FALSE,
       
   259   );
       
   260 
       
   261   // Convert short #FFF syntax to full #FFFFFF syntax.
       
   262   if (strlen($data['bgcolor']) == 4) {
       
   263     $c = $data['bgcolor'];
       
   264     $data['bgcolor'] = $c[0] . $c[1] . $c[1] . $c[2] . $c[2] . $c[3] . $c[3];
       
   265   }
       
   266 
       
   267   // Convert #FFFFFF syntax to hexadecimal colors.
       
   268   if ($data['bgcolor'] != '') {
       
   269     $data['bgcolor'] = hexdec(str_replace('#', '0x', $data['bgcolor']));
       
   270   }
       
   271   else {
       
   272     $data['bgcolor'] = NULL;
       
   273   }
       
   274 
       
   275   if (!empty($data['random'])) {
       
   276     $degrees = abs((float) $data['degrees']);
       
   277     $data['degrees'] = rand(-1 * $degrees, $degrees);
       
   278   }
       
   279 
       
   280   if (!image_rotate($image, $data['degrees'], $data['bgcolor'])) {
       
   281     watchdog('image', 'Image rotate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
       
   282     return FALSE;
       
   283   }
       
   284   return TRUE;
       
   285 }
       
   286 
       
   287 /**
       
   288  * Image dimensions callback; Rotate.
       
   289  *
       
   290  * @param $dimensions
       
   291  *   Dimensions to be modified - an array with components width and height, in
       
   292  *   pixels.
       
   293  * @param $data
       
   294  *   An array of attributes to use when performing the rotate effect containing
       
   295  *   the following items:
       
   296  *   - "degrees": The number of (clockwise) degrees to rotate the image.
       
   297  *   - "random": A boolean indicating that a random rotation angle should be
       
   298  *     used for this image. The angle specified in "degrees" is used as a
       
   299  *     positive and negative maximum.
       
   300  */
       
   301 function image_rotate_dimensions(array &$dimensions, array $data) {
       
   302   // If the rotate is not random and the angle is a multiple of 90 degrees,
       
   303   // then the new dimensions can be determined.
       
   304   if (!$data['random'] && ((int) ($data['degrees']) == $data['degrees']) && ($data['degrees'] % 90 == 0)) {
       
   305     if ($data['degrees'] % 180 != 0) {
       
   306       $temp = $dimensions['width'];
       
   307       $dimensions['width'] = $dimensions['height'];
       
   308       $dimensions['height'] = $temp;
       
   309     }
       
   310   }
       
   311   else {
       
   312     $dimensions['width'] = $dimensions['height'] = NULL;
       
   313   }
       
   314 }