- Patch #373613 by drewish, quicksketch: working around some Debian issues. They ship a different GD library.
parent
898a7db70c
commit
a4ee7092e1
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue