Commit a4ee7092 authored by Dries's avatar Dries

- Patch #373613 by drewish, quicksketch: working around some Debian issues. ...

- Patch #373613 by drewish, quicksketch: working around some Debian issues.  They ship a different GD library.
parent 898a7db7
......@@ -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);
......@@ -240,6 +239,29 @@ function image_resize(stdClass $image, $width, $height) {
return image_toolkit_invoke('resize', $image, array($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.
*
......@@ -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)) {
......
......@@ -145,6 +145,19 @@ class ImageToolkitTestCase extends DrupalWebTestCase {
$this->assertEqual($calls['crop'][0][4], 10, t('Height was computed and passed correctly'));
}
/**
* 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.
*/
......@@ -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.
......
......@@ -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()
......@@ -112,6 +113,14 @@ function image_test_resize(stdClass $image, $width, $height) {
return TRUE;
}
/**
* 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.
*/
......
......@@ -97,6 +97,76 @@ function image_gd_resize(stdClass $image, $width, $height) {
return TRUE;
}
/**
* 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.
*
......@@ -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);
}
......
......@@ -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.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment