diff options
author | Dries Buytaert <dries@buytaert.net> | 2009-03-10 09:43:01 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2009-03-10 09:43:01 +0000 |
commit | a4ee7092e1ebfe3cc2387ad4b72f723080601cd4 (patch) | |
tree | 9fe46fe0e9dc56a742f139cba4a857e8aff1c0d9 | |
parent | 898a7db70c69cdaf85505506beb391ead369f816 (diff) | |
download | brdo-a4ee7092e1ebfe3cc2387ad4b72f723080601cd4.tar.gz brdo-a4ee7092e1ebfe3cc2387ad4b72f723080601cd4.tar.bz2 |
- Patch #373613 by drewish, quicksketch: working around some Debian issues. They ship a different GD library.
-rw-r--r-- | includes/image.inc | 30 | ||||
-rw-r--r-- | modules/simpletest/tests/image.test | 80 | ||||
-rw-r--r-- | modules/simpletest/tests/image_test.module | 15 | ||||
-rw-r--r-- | modules/system/image.gd.inc | 76 | ||||
-rw-r--r-- | modules/system/system.api.php | 1 |
5 files changed, 186 insertions, 16 deletions
diff --git a/includes/image.inc b/includes/image.inc index 6f94810e0..a1e674cc1 100644 --- a/includes/image.inc +++ b/includes/image.inc @@ -226,12 +226,11 @@ function image_scale(stdClass $image, $width = NULL, $height = NULL, $upscale = * The target width, in pixels. * @param $height * The target height, in pixels. - * @param $toolkit - * An optional override of the default image toolkit. * @return * TRUE or FALSE, based on success. * * @see image_load() + * @see image_gd_resize() */ function image_resize(stdClass $image, $width, $height) { $width = (int) round($width); @@ -241,6 +240,29 @@ function image_resize(stdClass $image, $width, $height) { } /** + * Rotate an image by the given number of degrees. + * + * @param $image + * An image object returned by image_load(). + * @param $degrees + * The number of (clockwise) degrees to rotate the image. + * @param $background + * An hexadecimal integer specifying the background color to use for the + * uncovered area of the image after the rotation. E.g. 0x000000 for black, + * 0xff00ff for magenta, and 0xffffff for white. For images that support + * transparency, this will default to transparent. Otherwise it will + * be white. + * @return + * TRUE or FALSE, based on success. + * + * @see image_load() + * @see image_gd_rotate() + */ +function image_rotate(stdClass $image, $degrees, $background = NULL) { + return image_toolkit_invoke('rotate', $image, array($degrees, $background)); +} + +/** * Crop an image to the rectangle specified by the given rectangle. * * @param $image @@ -258,6 +280,7 @@ function image_resize(stdClass $image, $width, $height) { * * @see image_load() * @see image_scale_and_crop() + * @see image_gd_crop() */ function image_crop(stdClass $image, $x, $y, $width, $height) { $aspect = $image->info['height'] / $image->info['width']; @@ -279,6 +302,7 @@ function image_crop(stdClass $image, $x, $y, $width, $height) { * TRUE or FALSE, based on success. * * @see image_load() + * @see image_gd_desaturate() */ function image_desaturate(stdClass $image) { return image_toolkit_invoke('desaturate', $image); @@ -307,6 +331,7 @@ function image_desaturate(stdClass $image) { * @see image_save() * @see image_get_info() * @see image_get_available_toolkits() + * @see image_gd_load() */ function image_load($file, $toolkit = FALSE) { if (!$toolkit) { @@ -337,6 +362,7 @@ function image_load($file, $toolkit = FALSE) { * TRUE or FALSE, based on success. * * @see image_load() + * @see image_gd_save() */ function image_save(stdClass $image, $destination = NULL) { if (empty($destination)) { diff --git a/modules/simpletest/tests/image.test b/modules/simpletest/tests/image.test index 2348b28e1..4be01c773 100644 --- a/modules/simpletest/tests/image.test +++ b/modules/simpletest/tests/image.test @@ -146,6 +146,19 @@ class ImageToolkitTestCase extends DrupalWebTestCase { } /** + * Test the image_rotate() function. + */ + function testRotate() { + $this->assertTrue(image_rotate($this->image, 90, 1), t('Function returned the expected value.')); + $this->assertToolkitOperationsCalled(array('rotate')); + + // Check the parameters. + $calls = image_test_get_all_calls(); + $this->assertEqual($calls['rotate'][0][1], 90, t('Degrees were passed correctly')); + $this->assertEqual($calls['rotate'][0][2], 1, t('Background color was passed correctly')); + } + + /** * Test the image_crop() function. */ function testCrop() { @@ -193,7 +206,7 @@ class ImageToolkitGdTestCase extends DrupalWebTestCase { function getInfo() { return array( 'name' => t('Image GD manipulation tests'), - 'description' => t('Check that core image manipulations work properly: scale, resize, crop, scale and crop, and desaturate.'), + 'description' => t('Check that core image manipulations work properly: scale, resize, rotate, crop, scale and crop, and desaturate.'), 'group' => t('Image API'), ); } @@ -304,18 +317,63 @@ class ImageToolkitGdTestCase extends DrupalWebTestCase { 'height' => 8, 'corners' => array_fill(0, 4, $this->black), ), - 'desaturate' => array( - 'function' => 'desaturate', - 'arguments' => array(), - 'height' => 20, - 'width' => 40, - // Grayscale corners are a bit funky. Each of the corners are a shade of - // gray. The values of these were determined simply by looking at the - // final image to see what desaturated colors end up being. - 'corners' => array(array_fill(0, 3, 76) + array(3 => 0), array_fill(0, 3, 149) + array(3 => 0), array_fill(0, 3, 29) + array(3 => 0), array_fill(0, 3, 0) + array(3 => 127)), - ), ); + // Systems using non-bundled GD2 don't have imagerotate. Test if available. + if (drupal_function_exists('imagerotate')) { + $operations += array( + 'rotate_5' => array( + 'function' => 'rotate', + 'arguments' => array(5, 0xFF00FF), // Fuchsia background. + 'width' => 42, + 'height' => 24, + 'corners' => array_fill(0, 4, $this->fuchsia), + ), + 'rotate_90' => array( + 'function' => 'rotate', + 'arguments' => array(90, 0xFF00FF), // Fuchsia background. + 'width' => 20, + 'height' => 40, + 'corners' => array($this->fuchsia, $this->red, $this->green, $this->blue), + ), + 'rotate_transparent_5' => array( + 'function' => 'rotate', + 'arguments' => array(5), + 'width' => 42, + 'height' => 24, + 'corners' => array_fill(0, 4, $this->transparent), + ), + 'rotate_transparent_90' => array( + 'function' => 'rotate', + 'arguments' => array(90), + 'width' => 20, + 'height' => 40, + 'corners' => array($this->transparent, $this->red, $this->green, $this->blue), + ), + ); + } + + // Systems using non-bundled GD2 don't have imagefilter. Test if available. + if (drupal_function_exists('imagefilter')) { + $operations += array( + 'desaturate' => array( + 'function' => 'desaturate', + 'arguments' => array(), + 'height' => 20, + 'width' => 40, + // Grayscale corners are a bit funky. Each of the corners are a shade of + // gray. The values of these were determined simply by looking at the + // final image to see what desaturated colors end up being. + 'corners' => array( + array_fill(0, 3, 76) + array(3 => 0), + array_fill(0, 3, 149) + array(3 => 0), + array_fill(0, 3, 29) + array(3 => 0), + array_fill(0, 3, 0) + array(3 => 127) + ), + ), + ); + } + foreach ($files as $file) { foreach ($operations as $op => $values) { // Load up a fresh image. diff --git a/modules/simpletest/tests/image_test.module b/modules/simpletest/tests/image_test.module index 07f59461d..ed2cd320f 100644 --- a/modules/simpletest/tests/image_test.module +++ b/modules/simpletest/tests/image_test.module @@ -34,6 +34,7 @@ function image_test_reset() { 'save' => array(), 'settings' => array(), 'resize' => array(), + 'rotate' => array(), 'crop' => array(), 'desaturate' => array(), ); @@ -46,8 +47,8 @@ function image_test_reset() { * * @return * An array keyed by operation name ('load', 'save', 'settings', 'resize', - * 'crop', 'desaturate') with values being arrays of parameters passed to - * each call. + * 'rotate', 'crop', 'desaturate') with values being arrays of parameters + * passed to each call. */ function image_test_get_all_calls() { return variable_get('image_test_results', array()); @@ -58,7 +59,7 @@ function image_test_get_all_calls() { * * @param $op * One of the image toolkit operations: 'load', 'save', 'settings', 'resize', - * 'crop', 'desaturate'. + * 'rotate', 'crop', 'desaturate'. * @param $args * Values passed to hook. * @see image_test_get_all_calls() @@ -113,6 +114,14 @@ function image_test_resize(stdClass $image, $width, $height) { } /** + * Image tookit's rotate operation. + */ +function image_test_rotate(stdClass $image, $degrees, $background = NULL) { + _image_test_log_call('rotate', array($image, $degrees, $background)); + return TRUE; +} + +/** * Image tookit's desaturate operation. */ function image_test_desaturate(stdClass $image) { diff --git a/modules/system/image.gd.inc b/modules/system/image.gd.inc index 2ba31bbc6..a67ecf470 100644 --- a/modules/system/image.gd.inc +++ b/modules/system/image.gd.inc @@ -98,6 +98,76 @@ function image_gd_resize(stdClass $image, $width, $height) { } /** + * Rotate an image the given number of degrees. + * + * @param $image + * An image object. The $image->resource, $image->info['width'], and + * $image->info['height'] values will be modified by this call. + * @param $degrees + * The number of (clockwise) degrees to rotate the image. + * @param $background + * An hexadecimal integer specifying the background color to use for the + * uncovered area of the image after the rotation. E.g. 0x000000 for black, + * 0xff00ff for magenta, and 0xffffff for white. For images that support + * transparency, this will default to transparent. Otherwise it will + * be white. + * @return + * TRUE or FALSE, based on success. + * + * @see image_rotate() + */ +function image_gd_rotate(stdClass $image, $degrees, $background = NULL) { + // PHP installations using non-bundled GD do not have imagerotate. + if (!drupal_function_exists('imagerotate')) { + watchdog('image', 'The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', array('%file' => $image->source)); + return FALSE; + } + + $width = $image->info['width']; + $height = $image->info['height']; + + // Convert the hexadecimal background value to a color index value. + if (isset($background)) { + $rgb = array(); + for ($i = 16; $i >= 0; $i -= 8) { + $rgb[] = (($background >> $i) & 0xFF); + } + $background = imagecolorallocatealpha($image->resource, $rgb[0], $rgb[1], $rgb[2], 0); + } + // Set the background color as transparent if $background is NULL. + else { + // Get the current transparent color. + $background = imagecolortransparent($image->resource); + + // If no transparent colors, use white. + if ($background == 0) { + $background = imagecolorallocatealpha($image->resource, 255, 255, 255, 0); + } + } + + // Images are assigned a new color pallete when rotating, removing any + // transparency flags. For GIF images, keep a record of the transparent color. + if ($image->info['extension'] == 'gif') { + $transparent_index = imagecolortransparent($image->resource); + if ($transparent_index != 0) { + $transparent_gif_color = imagecolorsforindex($image->resource, $transparent_index); + } + } + + $image->resource = imagerotate($image->resource, 360 - $degrees, $background); + + // GIFs need to reassign the transparent color after performing the rotate. + if (isset($transparent_gif_color)) { + $background = imagecolorexactalpha($image->resource, $transparent_gif_color['red'], $transparent_gif_color['green'], $transparent_gif_color['blue'], $transparent_gif_color['alpha']); + imagecolortransparent($image->resource, $background); + } + + $image->info['width'] = imagesx($image->resource); + $image->info['height'] = imagesy($image->resource); + return TRUE; +} + +/** * Crop an image using the GD toolkit. * * @param $image @@ -144,6 +214,12 @@ function image_gd_crop(stdClass $image, $x, $y, $width, $height) { * @see image_desaturate() */ function image_gd_desaturate(stdClass $image) { + // PHP installations using non-bundled GD do not have imagefilter. + if (!drupal_function_exists('imagefilter')) { + watchdog('image', 'The image %file could not be rotated because the imagefilter() function is not available in this PHP installation.', array('%file' => $image->source)); + return FALSE; + } + return imagefilter($image->resource, IMG_FILTER_GRAYSCALE); } diff --git a/modules/system/system.api.php b/modules/system/system.api.php index 7e77e7dcd..ab0e5eb07 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -377,6 +377,7 @@ function hook_init() { * - 'save': Required. See image_gd_save() for usage. * - 'settings': Optional. See image_gd_settings() for usage. * - 'resize': Optional. See image_gd_resize() for usage. + * - 'rotate': Optional. See image_gd_rotate() for usage. * - 'crop': Optional. See image_gd_crop() for usage. * - 'desaturate': Optional. See image_gd_desaturate() for usage. * |